IPC之——信号量集(多个信号量)
如果两个进程不仅需要同步,还要保证先后执行顺序,就要用两个信号量(互斥锁)来解决
//栅栏模型:实现以下框架中的四个子进程 所有进程做完任务后 在一起执行下一次
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdlib.h>
#include <signal.h>
#define PROCESS_NR 4
void sigFunc(int signo)
{
int semId;
semId=semget(0x555,PROCESS_NR+1,IPC_CREAT|0600);
if(semId>0){
semctl(semId,0,IPC_RMID);
}
exit(1);
}
void p_lock(int idx,int semId);
void waitZero(int semId);
void doWork(int idx,int semId);
int main(void)
{
int semId,i;
pid_t pid;
////////////////////////////////
//对应的下标的信号量控制对应的子进程 最后一个信号量控制父进程
semId=semget(0x555,PROCESS_NR+1,IPC_CREAT|0600);
if(semId==-1)
{
perror("create sem");
return 11;
}
//init sem value
unsigned short vals[PROCESS_NR+1]={0};//对多个信号量值进行初始化
if(semctl(semId,0,SETALL,vals)==-1)
{
perror("init sem val");
semctl(semId,0,IPC_RMID);
return 12;
}
////////////////////////////////
for(i=0;i<PROCESS_NR;i++)
{
pid=fork();
if(pid==-1) return 1;
else if(pid==0)//child process
{
doWork(i,semId);//i标识进程的编号
exit(0);
}
}
//
signal(SIGINT,sigFunc);
//parent
struct sembuf bufs[PROCESS_NR+1]={0};
for(i=0;i<PROCESS_NR;i++)//子进程
{
bufs[i].sem_num=i;
bufs[i].sem_op =1;
}
bufs[PROCESS_NR].sem_num=PROCESS_NR;//父亲的资源
bufs[PROCESS_NR].sem_op =PROCESS_NR;
////////////////////////////////////////
while(1)
{
waitZero(semId);
printf("========升起栅栏=======\n");
semop(semId,bufs,PROCESS_NR+1);
}
while(wait(NULL)!=-1)
;//empty
return 0;
}
void doWork(int idx,int semId)
{
pid_t pid=getpid();
int sec;
srand(pid);
while(1)
{
p_lock(idx,semId);
sec=rand()%10+1;
printf("%dth Do [%d] sec:%d\n",idx,pid,sec);
//随机休眠1-10s 模拟不同进程不同时侯做事情可能需要不同的时长
sleep(sec);
//通知父进程 该子进程已执行完毕
p_lock(PROCESS_NR,semId);
}
}
////////////////////////////////////////
void p_lock(int idx,int semId)
{
struct sembuf buf={.sem_num=idx,.sem_op=-1};
semop(semId,&buf,1);
}
void waitZero(int semId)
{
struct sembuf buf={.sem_num=PROCESS_NR,.sem_op=0};
semop(semId,&buf,1);
}