僵尸进程与文件共享

孤儿进程与僵尸进程

孤儿进程:

如果父进程先退出,子进程还没退出那么子进程的父进程将变为init进程。(注:任何一个进程都必须有父进程)

//生成孤儿进程int main(int argc, char *argv[]){pid_t pid = fork();if (pid < 0)err_exit("fork error");else if (pid > 0)exit(0);else{sleep(10);cout << "Child, ppid = " << getppid() << endl;}exit(0);}

僵尸进程:

如果子进程先退出,父进程还没退出,那么子进程必须等到父进程捕获到了子进程的退出状态才真正结束,否则这个时候子进程就成为僵尸进程。

//生成僵尸进程int main(int argc, char *argv[]){pid_t pid = fork();if (pid < 0)err_exit("fork error");else if (pid == 0)exit(0);else{sleep(50);}exit(0);}

附-查询父子进程状态

ps-le|grepmain

避免僵尸进程

signal(SIGCHLD,SIG_IGN);

//示例: 避免僵尸进程int main(int argc, char *argv[]){signal(SIGCHLD, SIG_IGN);pid_t pid = fork();if (pid < 0)err_exit("fork error");else if (pid == 0)exit(0);else{sleep(50);}exit(0);}文件共享

父进程的所有文件描述符都被复制到子进程中,就好像调用了dup函数,父进程和子进程每个相同的打开文件描述符共享一个文件表项(因此,父子进程共享同一个文件偏移量);

//根据上图: 理解下面这段程序和下图的演示int main(int argc, char *argv[]){signal(SIGCHLD, SIG_IGN);int fd = open("test.txt", O_WRONLY|O_CREAT|O_TRUNC, 0666);if (fd == -1)err_exit("file open error");cout << "We Don`t flash memory\n";char buf[BUFSIZ];bzero(buf, sizeof(buf));pid_t pid = fork();if (pid < 0)err_exit("fork error");else if (pid > 0){strcpy(buf, "Parent…");write(fd, buf, strlen(buf));close(fd);cout << "fd = " << fd << endl;exit(0);}else if (pid == 0){strcpy(buf, "Child…");write(fd, buf, strlen(buf));close(fd);cout << "fd = " << fd << endl;exit(0);}}

。因此我们不推荐使用vfork,,因为几乎每一个vfork的实现,

vfork子进程与父进程共享数据段,因此父子进程对数据的更新是同步的;

2.fork父、子进程的执行次序是未知的,取决于操作系统的调度算法

vfork:子进程先运行,父进程后运行;

//示例1:vfork出错情况//在Linux 2.6内核上会持续执行,不会退出//而在Linux 3.13内核上, 则会引发core dumpint main(){int iNumber = 0;pid_t pid = vfork();if (pid == -1){perror("fork");return -1;}else if (pid > 0){cout << "In Parent Program…" << endl;cout << "iNumber = " << iNumber << endl;cout << "pid = " << static_cast<int>(getpid());cout << "\t ppid = " << static_cast<int>(getppid()) << endl;//_exit(0);}else if (pid == 0){iNumber ++;cout << "In Child Program…" << endl;cout << "iNumber = " << iNumber << endl;cout << "pid = " << static_cast<int>(getpid());cout << "\t ppid = " << static_cast<int>(getppid()) << endl;//_exit(0);}return 0;}

//示例2: 父进程/子进程修改全局数据的情况int main(){int iNumber = 10;cout << "Before vfork, pid = " << getpid() << endl;//对比fork()pid_t pid = vfork();if (pid == -1)err_exit("fork");else if (pid > 0){sleep(4);cout << "Parent, iNumber: " << iNumber << endl;}else if (pid == 0){++ iNumber;cout << "Child, iNumber = " << iNumber << endl;_exit(0);}return 0;}//示例3:用vfork执行当前目录下的hello程序int main(){int iNumber = 0;pid_t pid = vfork();if (pid == -1){perror("fork");return -1;}else if (pid > 0){cout << "In Parent Program…" << endl;cout << "iNumber = " << iNumber << endl;cout << "pid = " << static_cast<int>(getpid());cout << "\t ppid = " << static_cast<int>(getppid()) << endl;}else if (pid == 0){iNumber ++;cout << "In Child Program…" << endl;cout << "iNumber = " << iNumber << endl;cout << "pid = " << static_cast<int>(getpid());cout << "\t ppid = " << static_cast<int>(getppid()) << endl;//将自己写的程序启动起来execve("./hello",NULL,NULL);_exit(0);}return 0;}

一个人最大的破产是绝望,最大的资产是希望。

僵尸进程与文件共享

相关文章:

你感兴趣的文章:

标签云: