linux编程问题:父进程打印两个子进程pid的问题,我用wait(),可结果不太对,求帮助,万谢

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux编程问题:父进程打印两个子进程pid的问题,我用wait(),可结果不太对,求帮助,万谢相关的知识,希望对你有一定的参考价值。

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
pid_t getpid(void);
pid_t getppid(void);
这是我的程序
main()

int x,y;
while((x=fork())==-1);
if(x==0)

pid_t SubProcess1ID=getpid();
printf("SubProcess1 pid:%d\n",SubProcess1ID);
while((y=fork())==-1);
if(y==0)

pid_t SubProcess2ID=getpid();
printf("SubProcess2 pid:%d\n",SubProcess2ID);


else

pid_t SubProcessID1=wait(0);
pid_t SubProcessID2=wait(0);
pid_t ParentProcessID=getppid();
printf("ParentPrintChild1 pid:%d\nParentPrintChild2 pid:%d\nParentProcess pid:%d\n",SubProcessID1,SubProcessID2,ParentProcessID);



输出结果是
SubProcess1 pid:6281
SubProcess2 pid:6282
ParentPrintChild1 pid:6281
ParentPrintChild2 pid:-1
ParentProcess pid:3455

ParentPrintChild2 pid:-1这个是第二个子进程没能释放吗?为什么会这样呢,我要怎么改呢,我想让父进程打印子进程的pid啊,谢谢

你是父进程创建了一个子进程,在子进程中又创建了一个子进程(这个子进程是原本的父进程的孙子进程),所以原本的父进程只有一个子进程,当你输出第二个的时候,当然就是返回默认值-1了。追问

谢谢你,我想问一下,父进程有没有办法得到第二个子进程的pid呢?

追答

不能吧,我也不太确定

参考技术A fork()的问题

建议你再好好看一下fork
man fork

这个相关例子很多的
另外fork出去以后,所有进程其实是等价的,只是并发进行

Linux高性能服务器编程:多进程编程

1. fork系统调用

pid_t fork();

该函数的每次调用都返回两次,在父进程中返回子进程的PID,在子进程中则返回0. 该返回值是后续代码判断当前进程是父进程还是子进程的依据。fork调用失败时返回-1,并设置errno。

fork函数复制当前进程,在内核进程表中创建一个新的进程表项。新的进程表项有很多属性和原进程相同。比如堆指针、栈指针和标志寄存器的值。

子进程和父进程完全相同,同时它还会复制父进程的数据(堆数据、栈数据和静态数据)。数据的复制采用的是所谓的写时复制,即只有在任一进程对数据执行了写操作时,复制才会发生(先是缺页中断,然后操作系统给子进程分配内存并复制父进程的数据)。

创建子进程后,父进程中打开的文件描述符默认在子进程中也是打开的,且文件描述符的引用计数加1.

 

2. exec系统调用

在子进程中执行其他程序,即替换当前进程映像。

 

3.处理僵尸进程

当子进程结束运行时,内核不会立即释放该进程的进程表表项,一满足父进程后续对该子进程退出信息的查询。在子进程结束运行之后,父进程读取其退出状态之前,称该子进程处于僵尸态。另一种使子进程进入僵尸态的情况是:父进程结束或异常终止,而子进程继续运行,此时子进程的PPID将被操作系统设置为1,即init进程。

 

4.管道

管道能在父子进程间传递数据,利用的是fork调用之后两个管道文件描述符(fd[0]和fd[1])都保持打开。

管道只能用于有关联的两个进程间的通信。

 

5. 信号量

使用二进制信号量。

使用一个普通变量来模拟二进制信号量是行不通的,因为所有高级语言都没有一个原子操作可以同时完成如下两部操作:

检测变量是否为true/false,如果是则再将它设置为false/true。

 

int semget(key_t key, int num_sems, int sem_flags);

创建一个新的信号量集,或者获取一个已经存在的信号量集。

key参数是一个键值,用来标识一个全局唯一的信号量集,就像文件名全局唯一地标识一个文件一样。要通过信号量通信的进程需要使用相同的键值来创建/获取该信号量。

 

int semop(int sim_id, struct sembuf* sem_ops, size_t num_sem_ops);

sim_id参数是由semget调用返回的信号量集标识符,用以指定被操作的目标信号量集。

int semctl(int sem_id, int sem_num, int command, ...);  允许调用者对信号量进行直接控制。

 

6. 共享内存

共享内存是最高效的IPC机制,因为它不涉及进程之间的任何数据传输。但必须使用其他辅助手段来同步进程对共享内存的访问。

int shmget(key_t key, size_t size, int shmflg);

创建一段新的共享内存,或者获取已经存在的共享内存。

key是一个键值,用来标识一段全局唯一的共享内存。函数成功时返回一个正整数值,是共享内存的标识符。

 

void* shmat(int shm_id, const void* shm_addr, int shmflg); //关联

int shmdt(const void* shm_addr);  //分离

 

7. 消息队列

消息队列是在两个进程之间传递二进制块数据的一种简单有效的方式。

以上是关于linux编程问题:父进程打印两个子进程pid的问题,我用wait(),可结果不太对,求帮助,万谢的主要内容,如果未能解决你的问题,请参考以下文章

linux 编程问题:子进程1和2为啥也能对管道进行操作?

linux系统编程:进程控制(fork)

Linux高性能服务器编程:多进程编程

多进程编程

Linux下复杂PC问题——多进程编程/信号量通信/共享存储区

linux下fork两子进程为啥只有一个读取到pipe的内容?