欢迎光临散文网 会员登陆 & 注册

Linux--进程创建总结

2023-03-18 13:53 作者:圣母和正负喜欢没办法  | 我要投稿

1 fork:子进程是父进程副本,不知道父子进程启动顺序,复制父进程资源。

2 vfork: 不创建子进程了,子进程和父进程共享数据段,创建的子进程先于父进程进行。

3 clone: 创建线程使用pthread库,更精确指定要共享的内容。

fork:

#include <stdio.h>

#include <stdlib.h>

#include <sys/types.h>

#include <unistd.h>

int main(){

int count = 1;

int child;

child = fork( );

if(child < 0){

 perror("fork failure ");

 exit(1);

 }else if(child == 0){

    printf("This is child, count is: %d (%p). and his pid is: %d\n", ++count, &count, getpid());

}else  {

    printf("This is parent,count is: %d (%p), his pid is: %d\n", count, &count, getpid());

}

exit(0);

}

1>运行结果里面可以看出父子两个进程的pid不同,堆栈和数据资源都是完全的复制

2>子进程改变了count的值,而父进程中的count没有被改变。

3>子进程与父进程count的地址(虚拟地址)是相同的(在内核中被映射的物理地址不同)

CW技术(写时复制)

一句话

父进程和子进程都设置成了只读模式,只有写入时,会有中断异常,异常处理函数为写进程复制一份新物理页,父子进程都拥有一块内容相同的物理页,异常函数返回,进程继续执行下去。

vfork

#include <stdio.h>

#include <stdlib.h>

#include <sys/types.h>

#include <unistd.h>

int main(){

int count = 1;

int child;

if((child = vfork()) < 0){

 perror("vfork failure ");

 exit(1);

 }else if((child=vfork()) == 0){

    printf("This is child, count is: %d (%p). and his pid is: %d\n", ++count, &count, getpid());

    exit(1);

}else  {

    printf("This is parent,count is: %d (%p), his pid is: %d\n", count, &count, getpid());

  exit(1);

}

exit(0);

}

vfork创建出的子进程(线程)共享了父进程的count变量,2者的count指向了同一个内存,所以子进程修改了count变量,父进程的 count变量同样受到了影响。

1>vfork创造出来的子进程还会导致父进程挂起,除非子进程exit或者execve才会唤起父进程

2>vfok创建出来的子进程共享了父进程的所有内存,包括栈地址,直至子进程使用execv启动新的应用程序为止

3>由vfork创建出来得子进程不应该使用return返回调用者,或者使用exit()退出,但是它可以使用_exit()函数来退出

@vfork就是老小欺负老大,老小要吃雪糕,老大有,于是先吃老大的,等到父母执行exec买了新雪糕再把吃过的还给老大。记住exec不创建新进程,只是用新程序替换原正文、数据、堆栈,id不变。

clone

选择性的继承父进程的资源,你可以选择想vfork一样和父进程共享一个虚存空间,从而使创造的是线程,你也可以不和父进程共享,你甚至可以选择创造出来的进程和父进程不再是父子关系,而是兄弟关系。

来源网上程序:

#include <stdio.h>

#include <malloc.h>

#include <sched.h>

#include <signal.h>

#include <sys/types.h>

#include <unistd.h>

#define FIBER_STACK 8192

int a;

void * stack;

int do_something()

{

    printf("This is son, the pid is:%d, the a is: %d\n", getpid(), ++a);

    free(stack); 

    exit(1);

}

int main()

{

    void * stack;

    a = 1;

    stack = malloc(FIBER_STACK);

    if(!stack)

    {

        printf("The stack failed\n");

        exit(0);

    }

printf("creating son thread!!!\n");

clone(&do_something, (char *)stack + FIBER_STACK, CLONE_VM|CLONE_VFORK, 0);  

printf("This is father, my pid is: %d, the a is: %d\n", getpid(), a);

exit(1);

}

创建一个线程(子进程共享了父进程虚存空间,没有自己独立的虚存空间不能称其为进程)。父进程被挂起当子线程释放虚存资源后再继续执行。

Linux--进程创建总结的评论 (共 条)

分享到微博请遵守国家法律