首页 > 其他分享 >fork函数

fork函数

时间:2022-11-03 11:32:47浏览次数:62  
标签:fork 函数 int pid sleep getpid 进程 include

关于linux下fork函数的调用

父进程会产生子进程,子进程会获得父进程的数据空间,堆和栈的副本。(注意:不是共享)

fork函数调用一次会返回两次

主要注意两点处理:1.子进程先退出,内核向父进程发送SIGCHLD信号,如果父进程不处理这个信号的话,子进程会变成僵尸进程

2.父进程先退出,子进程会变成孤儿进程,将会被1号进程收养,由于1号进程对它完成状态收集工作。(孤儿进程没什么危害)

问题1造成后果:父进程没处理子进程退出的信息,内核就不会释放这个数据结构,子进程的进程编号会被一直占用,大量僵尸进程会导致没有可用的进程号从而系统无法产生新的进程。(系统的进程号是有限的,释放掉一个进程号会有一段等待时间才会再次调用那个进程号)

僵尸进程产生:(让子进程先结束)

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
int main()
{
int pid=fork();

if(pid==0)
{
printf("这是子进程%d\n",getpid());
sleep(5);
}
if(pid>0)
{
printf("这是父进程%d\n",getpid());
slep(10);
}
}

fork函数_父进程

僵尸进程在父进程退出后也会消失。父进程不退出的话会一直存在

三种解决方法:1.在父进程中忽略SIGCHLD信号

fork函数_子进程_02

运行观测:没有产生僵尸进程

fork函数_子进程_03


2.在父进程中增加等待子进程退出的代码(使用wait函数)

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<signal.h>
#include<sys/types.h>
#include<sys/wait.h>
int main()
{
// signal(SIGCHLD,SIG_IGN);
int pid=fork();

if(pid==0)
{
printf("这是子进程%d\n",getpid());
sleep(5);
}
if(pid>0)
{
printf("这是父进程%d\n",getpid());
int sts;
wait(&sts);
sleep(10);
}
}

运行效果和上面一样;

但是有个问题是会阻塞在wait处等待,此时父进程做不了其他事情。

3.设置SIGCHLD的信号处理函数。在信号处理函数中调用wait,只要信号到达了,不需要等待

void func(int sig)
{
int sts;
wait(&sts);
}
int main()
{
signal(SIGCHLD,func);

int pid=fork();

if(pid==0)
{
printf("这是子进程%d\n",getpid());
sleep(5);
}
if(pid>0)
{
printf("这是父进程%d\n",getpid());
sleep(10);//子进程5秒后退出,信号是软信号会中断此信号的调用
sleep(10);
}
}




标签:fork,函数,int,pid,sleep,getpid,进程,include
From: https://blog.51cto.com/u_15525394/5819249

相关文章

  • Oracle使用存储函数从身份证中提取出生年月
    CREATEORREPLACEFUNCTIONnianyue(CARDVARCHAR2)RETURNVARCHAR2ISNYDATE;BEGINSELECTto_date(to_char(substr(REPLACE(CARD,'',''),7,8)),'YYYYMMDD')I......
  • Oracle使用存储函数从身份证中提取性别
    CREATEORREPLACEFUNCTIONXINGBIE(CARDVARCHAR2)RETURNVARCHAR2ISXBVARCHAR2(3);BEGINSELECTDECODE(MOD(TO_NUMBER(SUBSTR(REPLACE(CARD,'',''),17,......
  • Oracle使用存储函数效验手机号是否正确
    CREATEORREPLACEFUNCTIONXIAOYAN_D(PHONENUMBERINVARCHAR2)RETURNNUMBERASFANNUMBER(11);BEGINSELECTLTRIM(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(......
  • Oracle创建创建清洗效验邮箱函数
    --创建清洗效验邮箱函数CREATEORREPLACEFUNCTIONXIAOYAN_Y(PHONENUMBERINVARCHAR2)RETURNVARCHAR2ASxiVARCHAR2(30);FANNUMBER(10);BEGINSELECTREPLA......
  • mysql 窗口函数
    语法结构窗口函数的语法结构:函数OVER([PARTITIONBY字段名ORDERBY字段名ASC|DESC])函数OVER窗口名…WINDOW窗口名AS([PARTITIONBY字段名ORDERBY字......
  • Mysql的INTERVAL()函数和INTERVAL关键字
    Mysql的INTERVAL()函数和INTERVAL关键字  一,INTERVAL()函数INTERVAL()函数可以返回分段后的结果,语法如下:INTERVAL(N,N1,N2,N3,..........)其中,N是要判断的数值,N1,N2......
  • Java函数式编程(1):Lambda表达式(1)
    您好,我是湘王,这是我的博客园,欢迎您来,欢迎您再来~ Java在其技术发展周期中经历过几次比较重要的变化,如果不是这几次比较重要的变化,恐怕不会有现在这样的江湖地位。个人看......
  • 实验三 函数应用编程
    实验任务一task1.c#include<stdio.h>#include<stdlib.h>#include<time.h>#include<Windows.h>#defineN80voidprint_text(intline,intcol,chartext[]);voidpri......
  • C语言 模拟实现字符串函数 看着一篇够了
    C语言模拟实现字符串操作的库函数求字符串长度strlen思路1.如果碰到\0就代表字符串已经到了末尾size_tmy_strlen(constchar*str){ assert(str!=NULL); //......
  • 字符操作函数
    核心都是将字符串在传参时,由于形参int的限制转换为了每个字符对应的ASCII码然后进行判断和转换字符的判断分类函数返回值是该分类返回非0的正数,否则返回0 //字......