Linux 信号量

    需求:如何实现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;
}

    详见: http://blog.csdn.net/mybelief321/article/details/9086151

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值