需求:如何实现fork()后的子进程退出后,再退出父进程
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
pid_t result;
int sem_id;
result=fork();
if(result==-1)
{
perror("fork\n");
}else if(result==0)
{
printf("chind process wait for some seconds ...\n");
sleep(5);
printf("The returned value is %d in the child process(pid=%d)\n",result,getpid());
}else{
//int status;
//wait(status);
printf("The return value is %d in the father process(pid=%d)\n",result,getpid());
}
return 0;
}
上述代码,明显父进程先于子进程前退出
解决方案一: 在父进程中调用 wait() 方法,堵塞等待子进程退出
解决方案二: 利用信号量同步进程退出顺序.
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
// 当semctl参数为4个时,必须手动定义这个联合体
union semun
{
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *_buf;
};
// 初始化信号量
int init_sem(int sem_id,int init_value)
{
union semun sem_union;
sem_union.val=init_value;
if(semctl(sem_id,0,SETVAL,sem_union)==-1)
{
perror("init semphore");
return -1;
}
return 0;
}
// 删除信号量
int del_sem(int sem_id)
{
union semun sem_union;
if(semctl(sem_id,0,IPC_RMID,sem_union)==-1)
{
perror("delete semphore");
return -1;
}
return 0;
}
// p操作获取资源
int sem_p(int sem_id)
{
struct sembuf sem_b;
sem_b.sem_num = 0; // 单个信号量
sem_b.sem_op = -1; // -1表p操作
sem_b.sem_flg=SEM_UNDO; // 在进程退出时,自动释放信号量
if(semop(sem_id,&sem_b,1)==-1)
{
perror("p operation");
return -1;
}
return 0;
}
// v操作释放资源
int sem_v(int sem_id)
{
struct sembuf sem_b;
sem_b.sem_num = 0; // 信号量编号, 单个信号量
sem_b.sem_op = 1; // +1表V操作
sem_b.sem_flg=SEM_UNDO; // 在进程退出时,自动释放信号量
if(semop(sem_id,&sem_b,1)==-1)
{
perror("v operation");
return -1;
}
return 0;
}
int main(int argc,char **argv)
{
pid_t result;
int sem_id;
// key_t key=ftok() 产生唯一ipc键
sem_id=semget(ftok(".",'a'),1,0666|IPC_CREAT);
init_sem(sem_id,0); // 设置信号量为0
result=fork();
if(result==-1)
{
perror("fork\n");
}else if(result==0) // 子进程
{
printf("chind process wait for some seconds ...\n");
sleep(5);
printf("The returned value is %d in the child process(pid=%d)\n",result,getpid());
sem_v(sem_id); // v操作,资源数+1
}else{ // 父进程
sem_p(sem_id); // 此时资源计数为0,堵塞等待子进程释放资源,当资源数>0时才向下执行
printf("The return value is %d in the father process(pid=%d)\n",result,getpid());
sem_v(sem_id);
del_sem(sem_id);
}
return 0;
}
















