#小码农的一天#LINUX_C 进程控制总结

来源:互联网 发布:哥德巴赫猜想c语言ios 编辑:程序博客网 时间:2024/05/17 22:27

5.2进程控制

1.1 fork函数

#include<sys/types.h>

#include<unistd.h>

pid_t fork();

fork函数用来创建子进程,若创建成功,则返回进程子进程的进程标识符pid_t,若创建不成功返回-1。

子进程是父进程的一个副本,子进程从父进程那里得到了数据段和堆栈段的副本,并重新被分配新的内存(不与父进程共享内存)但对于只读代码段,一般情况下是以共享内存的方式访问的,子进程在被创建之后从调用fork函数的下一条语句开始执行。(现在为了提高效率,采用另外一种“写时复制“的技术)

注:写时复制,父进程和子进程共享数据段和堆栈段,但内核将其权限声明为对子进程为只读,当子进程需要改变堆栈内容时再生成改块内存的副本,通常他们是虚存的一页(最后一句我也不知道是什么意思)

有看到一句话,叫做 fork函数只是将父进程的环境复制到子进程中。

1.2 创建共享内存段

shmget申请一块内存段

shmat附在进程的虚拟的地址空间

用代码表示也就是这样:
int shmid = shmget(SIZE,KEY,IPC_CREAT|0777);

int *pint = shmat(shmid,0,0);

*pint = 100;//把共享内存的值设定为100



1.3 vfork 函数

vfork调用之后,父进程立刻被挂起,子进程开始执行(文中提到fork函数生成了进程之后立刻调用exec函数),直到子函数调用exec或者exit();

用代码表示就是这样

{

pid_t pid = vfork();

....要执行的命令....

_exit(0);

printf("父进程begain!");

.....父进程执行的命令.....

}

这个时候,如果把代码写好一点,扩充一点成这样

int main()

{

pid_t pid = vfork();

printf("under vfork()\n");

int var = 0;

if(pid  < 0)

{

printf("vfork error.\n");

return 1;

}

else(pid == 0)

{

val++;

printf("子进程执行完毕,并且已经改变了父进程的var的值");

_exit(0)

}

else

{

printf("after _exit \n");

}

printf("var = %d\n",var);

return 0;

}

那么,这段程序的输出结果应该是:
1. under fork

2. printf("子进程执行完毕,并且已经改变了父进程var的值");

3. under fork

4. after_exit

5. var = 1;

输出结果分析:
1.子进程开始跑了,输出under fork(很好理解吧)

2.若用vfork创建子进程成功,则pid 的值应该为0,这时候val++,输出printf();里面的内容(关于vfork,fork以及前面用来创建共享内存的shmget和shmat的参数和返回值的问题我一个一个man之后再写总结,英语不好,硬伤啊)

3.子进程退出,父进程开始从vfork函数下面开始跑

4.这时pid的值变为了用户识别号(博主printf得出来的不完整的推论,没办法只能先这么理解了,书上没有详说,估计和exit()的内部实现有关)所以输出else语句里面的内容。

5.vfork的方式直接使用父进程的内存区,不再自己创建内存区,所以var的值变成了1;(书中提到了一句,说这一机制在linux内存的虚拟页式管理的配合下,提供了很高的效率,现在还理解不了,有时间,有实力的小伙伴可以去了解了解,然后再回来教我,哈哈)

1.4 exec 函数

exec函数用来执行另外一个应用程序

分为六种格式:

execl execv execle execve execlp execvp

头都大了,明天再更新这六个的区别和shmat shmge vfork fork 的使用方法(参数类型,返回值)

明天星期六,我要多学点东西!

世界晚安!


0 0
原创粉丝点击