记录bug
今天写多进程的时候遇到了这样一个bug,我通过fork创建子进程,然后再让子进程fork创建子进程…直到一个终止条件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/wait.h> #define READMODE 0 #define WRITEMODE 1 int main () { int p[2 ]; pipe (p); int read_pipe = p[READMODE]; int write_pipe = p[WRITEMODE]; close (0 ); int pppid = 0 ; if ( (pppid = fork()) == 0 ) { while (1 ) { printf ("pid: %d\n" , getpid ()); pipe (p); close (write_pipe); int base_num; if (read (read_pipe, &base_num, sizeof (int )) == 0 ) { printf ("pid %d 我死了\n" ,getpid ()); close (p[READMODE]); close (p[WRITEMODE]); close (read_pipe); exit (0 ); } printf ("prime %d\n" , base_num); if (base_num == 31 ) { close (p[READMODE]); close (p[WRITEMODE]); close (read_pipe); exit (0 ); } int pid = fork(); if (pid > 0 ) { close (p[READMODE]); int x; while (read (read_pipe, &x, sizeof (int ))) { if (x % base_num != 0 ) { write (p[WRITEMODE], &x, sizeof (int )); } } close (read_pipe); int status = 0 ; printf ("pid %d done\n" , getpid ()); exit (0 ); } else { read_pipe = p[READMODE]; write_pipe = p[WRITEMODE]; } } } else { close (p[READMODE]); for (int i = 2 ; i <= 35 ; i++) { write (p[WRITEMODE], &i, sizeof (int )); } close (p[WRITEMODE]); int wpid; int status = 0 ; printf ("结束了" ); exit (0 ); } exit (0 ); }
发现最后进程都退出之后,命令行不动,除非输入一些东西或者放大缩小终端界面。。。 我目测原因是因为这样链式fork,并且每个父进程都在子进程前面exit,就会导致子进程成为孤儿进程,孤儿进程由init操作系统管理,也就是说,孤儿进程的父进程会变成system,不再是bash,原因应该是最后一个进程exit后,bash没有关于这个进程的信息,所以不会变化…但是具体原因不是很清楚,需要学完操作系统后再看。而且当我使用wait之后,所有父进程都卡住了…
An orphan process is a computer process whose parent process has finished or terminated, though it remains running itself.
In a Unix-like operating system any orphaned process will be immediately adopted by the special init system process: the kernel sets the parent to init. This operation is called re-parenting and occurs automatically. Even though technically the process has the “init” process as its parent, it is still called an orphan process since the process that originally created it no longer exists. In other systems orphaned processes are immediately terminated by the kernel. In modern Linux systems, an orphan process may be reparented to a “subreaper” process instead of init.
update: 原因是我没有关闭管道,导致阻塞…还要记得父进程要wait子进程。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/wait.h> #define READMODE 0 #define WRITEMODE 1 int main () { int p[2 ]; pipe (p); int read_pipe = p[READMODE]; int write_pipe = p[WRITEMODE]; close (0 ); int pppid = 0 ; if ( (pppid = fork()) == 0 ) { while (1 ) { pipe (p); close (write_pipe); int base_num; if (read (read_pipe, &base_num, sizeof (int )) <= 0 ) { close (p[READMODE]); close (p[WRITEMODE]); close (read_pipe); exit (0 ); } printf ("prime %d\n" , base_num); int pid = fork(); if (pid > 0 ) { close (p[READMODE]); int x; while (read (read_pipe, &x, sizeof (int ))) { if (x % base_num != 0 ) { write (p[WRITEMODE], &x, sizeof (int )); } } close (p[WRITEMODE]); close (read_pipe); wait ((int *)0 ); exit (0 ); } else { read_pipe = p[READMODE]; write_pipe = p[WRITEMODE]; } } } else { close (p[READMODE]); for (int i = 2 ; i <= 35 ; i++) { write (p[WRITEMODE], &i, sizeof (int )); } close (p[WRITEMODE]); wait ((int *)0 ); exit (0 ); } exit (0 ); }