做易拉宝设计的网站,新媒体运营工资一般多少,wordpress价格比较模板,单仁营销网站的建设进程创建#xff1a; ①使用fork函数创建一个进程#xff0c;创建的新进程被称为子进程。 #include unistd.h//头文件 pid_t fork(void); fork函数调用成功#xff0c;返回两次#xff1a; 返回值为0#xff0c; 代表当前进程为子进程#xff1b; 返回值为非负数…进程创建 ①使用fork函数创建一个进程创建的新进程被称为子进程。 #include unistd.h//头文件 pid_t fork(void); fork函数调用成功返回两次 返回值为0 代表当前进程为子进程 返回值为非负数代表当前进程为父进程(返回新子进程的ID) 调用失败返回值为-1.
②vfork函数也可以创建进程 区别 1 、vfork直接使用父进程存储空间不拷贝。 2 、 vfork保证子进程先运行当子进程调用exit退出后父进程才执行。 fork
#include sys/types.h
#include unistd.h
#include stdio.hint main()
{pid_t pid;pid_t pid2;pid_t retpid;pidgetpid();printf(before fork:pid%d\n,pid);retpidfork();pid2getpid();printf(after fork:pid%d\n,pid2);if(pidpid2){printf(this is father printretpid %d\n,retpid);}else{printf(this is child print,retpid %d,child pid%d\n,retpid,getpid());}return 0;
}vfork
#include sys/types.h
#include unistd.h
#include stdio.h
#include stdlib.hint main()
{pid_t pid;int cnt 0;pid vfork();if(pid 0){while(1){printf(cnt %d\n,cnt);printf(this is father printretpid %d\n,getpid());sleep(1);}}else if(pid 0){while(1){printf(this is child printretpid %d\n,getpid());sleep(1);cnt;if(cnt 3){exit(0);}}}return 0;
}运行结果 before fork:pid3082 after fork:pid3082 this is father printretpid 3083 after fork:pid3083 this is child print,retpid 0,child pid3083 进程创建时发生什么 fork调用之后代码段共享数据段copy。 不修改变量时共享变量。修改子进程数据父进程不改变。
现在很多实现并不执行父进程数据段、栈和堆的完全复制。作为替代使用了写时复制Copy-On-WriteCOW技术。 创建子进程的目的 ①一个父进程希望复制自己使父、子进程同时执行不同的代码段。这在网络服务进程中是常见的----父进程等待客户端的服务请求。当这种请求达到时父进程调用fork使子进程处理此请求。父进程继续等待下一个服务请求到达。 ②一个进程要执行一个不同的程序。这对shell是常见的情况。这种情况下子进程从fork返回后立即调用exec
进程退出 正常退出 1.Main函数调用return 2.进程调用exit标准c库 3.进程调用_exit或者_Exit属于系统调用 补充 4.进程最后一个线程返回 5.最后一个线程调用pthread_exit
异常退出 1.调用abort 2.当进程收到某些信号时如CTRLC 3.最后一个线程对取消cancellation请求做出响应
对于三个终止exit、_exit和_Exit实现这个的方法是将其退出状态exit status作为参数传递给函数。在异常终止时内核不是进程本身产生一个指示其异常终止原因的异常终止状态termination status。在任意情况下该终止进程的父进程都能用wait或waitpid函数取得其终止状态。
父进程等待子进程退出并收集子进程的退出状态 子进程退出状态不被收集变成僵尸zombie进程僵死进程 查看ps -aux|grep …能看到zzombie僵死进程
#include sys/types.h
#include sys/wait.hpid_t wait(int *status);//地址pid_t waitpid(pid_t pid,int *status,int options);
//参数3一般用WNOHANG不阻塞status参数是一个整型数指针 非空子进程退出状态放在它所指向的地址中 空不关心退出状态 exit正常终止子进程返回的状态则为真。这种情况需要执行宏WEXITSTATUS(status)取子进程传送给exit、_exit或_Exit参数的低8位。 如果其所有子进程都还在运行则阻塞如果一个子进程已终止正等待父进程获取其终止状态则取得该子进程的终止状态立即返回如果它没有任何子进程则立即出错返回. waitpid()有一个选项options可以使其不阻塞 #include sys/types.h
#include unistd.h
#include stdio.h
#include stdlib.hint main()
{pid_t pid;int cnt 0;int status 10;pid fork();if(pid 0){wait(status);printf(child quit! child status %d\n,WEXITSTATUS(status));while(1){printf(cnt %d\n,cnt);printf(this is father printretpid %d\n,getpid());sleep(1);}}else if(pid 0){while(1){printf(this is child printretpid %d\n,getpid());sleep(1);cnt;if(cnt 5){exit(3);}}}return 0;
}结果如下 this is child printretpid 3116 this is child printretpid 3116 this is child printretpid 3116 this is child printretpid 3116 this is child printretpid 3116 child quit! child status 3 cnt 0 this is father printretpid 3115 cnt 0
孤儿进程 父进程如果不等待子进程退出在子进程之前就结束了自己的“生命”此时子进程叫做孤儿进程 Linux避免系统存在过多的孤儿进程init进程收留孤儿进程变成孤儿进程的父进程