Linux的进程和线程.docx
《Linux的进程和线程.docx》由会员分享,可在线阅读,更多相关《Linux的进程和线程.docx(13页珍藏版)》请在冰豆网上搜索。
Linux的进程和线程
操作系统课程设计
实验报告册
班级:
131112
学号:
13111xxx
姓名:
xxxxx
教师:
目录
实验说明
重要提示
实验3
Linux的进程和线程
要求:
理解进程/线程的概念
掌握创建和终止进程/线程的方法
掌握与进程/线程控制相关的系统函数
实验编号
3
题目
Linux的进程和线程
实验目的
理解进程/线程的概念
掌握创建和终止进程/线程的方法
掌握与进程/线程控制相关的系统函数
实验内容
创建和终止进程/线程
使用进程/线程控制相关的系统函数
报告内容要求
(1)实现方法和思路
(2)测试及结果
报告正文
•getpid():
获得当前进程ID
•getppid():
获得当前进程的父进程的ID
•getuid():
获得用户ID
•getgid():
获得组ID
源代码:
#include
#include
#include
intmain(){
pid_tmyPid;
pid_tmyParentPid;
gid_tmyGid;
uid_tmyUid;
myPid=getpid();
myParentPid=getppid();
myGid=getgid();
myUid=getuid();
printf("myprocessidis%d\n",myPid);
printf("myparentisprocessidis%d\n",myParentPid);
printf("mygroupidis%d\n",myGid);
printf("myuseridis%d\n",myUid);
return0;
}
运行结果;
API函数
用途
fork
创建一个新的子进程
wait
将进程挂起直到子进程退出
signal
注册一个新的信号句柄
pause
将进程挂起直到捕获到信号
kill
向某个指定的进程发出信号
exit
正常中止当前进程
Wait函数
pid=wait(&status);
If(WIFEXITED(status)){
printf(“Childexitednormallywithstatus%d\n”,WEXITSTATUS(status));
}elseif(WIFSIGNALED(status)){
printf(“Childexitedbysignalwithstatus%d\n”,WTERMSIG(status));
}
源代码:
#include
#include
#include
intmain(){
pid_tret;
intstatus,i;
introle=-1;
ret=fork();
if(ret>0){
printf("Parent:
Thistheparentprocess(pid%d)\n",getpid());
for(i=0;i<6;i++){
printf("Parent:
Atcount%d\n",i);
sleep(3);}
ret=wait(&status);//防止僵尸进程的产生
role=0;}
else
if(ret==0){
printf("Child:
Thisthechildprocess(pid%d)\n",getpid());
for(i=0;i<6;i++){
printf("Chile:
Atcount%d\n",i);
sleep
(1);
}
role=1;
}
else{
printf("Parent:
Errortryingtofork()(%d)\n",errno);
}
printf("%s:
Exiting...\n",((role==0)?
"Parent":
"Child"));
return0;
}
运行结果:
signal函数
信号
说明
SIGHUP
挂起
SIGINT
键盘中断
SIGKILL
Kill信号
SIGUSR1
用户自定义信号
SIGUSR2
用户自定义信号
SIGPIPE
终止管道
SIGTERM
终止信号
源代码:
#include
#include
#include
#include
voidcatch_ctlc(intsig_num){
printf("CaughtControl-C\n");
fflush(stdout);//清除标准输出的缓存区
}
intmain(){
signal(SIGINT,catch_ctlc);
printf("Goahead,makemyday.\n");
pause();
return0;
}
运行结果:
•pause函数
–pause函数会把进程挂起,直到接收到信号。
在接收到以后,调用进程从pause中返回,继续进行。
如果进程捕获的信号已经注册了信号句柄,那么pause函数会在信号句柄被调用并返回之后才返回。
–pause原型:
•头文件
•intpause(void);
pid
说明
>0
信号发送到由pid指定的进程
0
信号发送到与调用进程同组的所有进程
-1
信号发送到所有进程(init进程除外)
<0
信号发送到由pid的绝对值指定的进程组中的所有进程
源代码:
#include
#include
#include
#include
#include
#include
voidusr1_handler(intsig_num){
printf("Parent(%d)gottheSIGUSR1\n",getpid());
}
intmain(){
pid_tret;
intstatus;
introle=-1;
ret=fork();
if(ret>0){
printf("Parent:
Thisistheparentprocess(pid%d)\n",getpid());
signal(SIGUSR1,usr1_handler);
role=0;
pause();
printf("Parent:
Awaitingchildexit\n");
ret=wait(&status);
}
else{
if(ret==0){
printf("Child:
Thisisthechildprocess(pid%d)\n",getpid());
role=1;
sleep
(1);
printf("Child:
SendingSIGUSR1topid%d\n",getppid());
kill(getppid(),SIGUSR1);
sleep
(2);
}else{
printf("Parent:
Errortryingtofork()(%d)\n",errno);
}
printf("%s:
Exiting…\n",((role==0)?
"Parent":
"Child"));
}
return0;
}
运行结果:
•exit函数
–终止调用进程。
传入exit的参数会返回给父进程,为wait或waitpid调用提供所需要的状态信息。
–exit原型:
•voidexit(intstatus);
–进程调用exit时还会向父进程发出SIGCHLD信号,释放当前进程占用的资源。
–这个函数调用十分重要,因为他会向Shell坏境表明状态时成功还是失败。
•线程函数
–头文件
–创建线程原型
•intpthread_create(pthread_t*thread,pthread_attr_t*attr,void*(*start_routine)(void*),void*arg);
•第一个参数为指向线程标示符的指针。
•第二个参数用来设置线程属性。
•第三个参数是线程运行函数的起始地址。
•最后一个参数是运行函数的参数。
•若成功则返回0,若失败则返回出错编号。
•线程函数
–终止线程原型
–intpthread_exit(void*retval);
源代码:
#include
#include
#include
#include
#include
void*myThread(void*arg){
printf("Threadran\n");
pthread_exit(arg);
}
intmain()
{
intret;
pthread_tmythread;
ret=pthread_create(&mythread,NULL,myThread,NULL);
if(ret!
=0){
printf("Cannotcreatepthread(%s)\n",strerror(errno));
exit(-1);
}
return0;
}
程序无输出内容
修改代码:
#include
#include
#include
#include
#include
void*myThread(void*arg){
printf("Threadran\n");
pthread_exit(arg);
}
intmain()
{
intret;
pthread_tmythread;
ret=pthread_create(&mythread,NULL,myThread,NULL);
if(ret!
=0){
printf("Cannotcreatepthread(%s)\n",strerror(errno));
exit(-1);
}
if(ret!
=1){
printf("11111111\n");
exit(-1);
}
return0;
}
运行结果:
•线程管理
–pthread_tpthread_self(void);//获得自己的线程描述符
void*myThread(void*arg)
{
pthread_tpt;
pt=pthread_self();
printf("Thread%xran!
\n",(int)pt);
pthread_exit(NULL);
}
•intpthread_join(pthread_tth,void**thread_return);
•参数th是想要加入的线程
•参数thread_return存储线程完成后的返回值,可以为NULL,表明不捕获线程的返回状态。
•返回值,0代表成功,非0代表失败的编号。
源代码;
#include
#include
void*myThread(void*arg){
printf("Thread%dstarted\n",(int)arg);
pthread_exit(arg);
}
#defineMAX_THREADS5
intmain(){
intret,i,status;
pthread_tthreadIds[MAX_THREADS];
for(i=0;iret=pthread_create(&threadIds[i],NULL,myThread,(void*)i);
if(ret!
=0){
printf("Errorcreatingthread%d\n",(void*)i);
}
}
for(i=0;iret=pthread_join(threadIds[i],(void**)&status);
if(ret!
=0){
printf("Errorjoiningthread%d\n",(void*)i);
}
else{
printf("Status=%d\n",status);
}
}
return0;
}
运行结果: