进程间通信--信号量
信号灯,主要作用:对于临界资源的一种保护机制。但是下面的程序当中,自己不是很理解。
1、一个是,对于什么样的资源进行保护,好像程序里面体现的不是很好,还是自己读不懂。
2、对于进程链创建-->打印的结果。不是很明白。
3、从请求资源到获取原子操作和结束原子操作过程,真的不太明白为什么会这样子写。
#include <unistd.h>
#include <limits.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#define PREMS S_IRUSR|S_IWUSR
void init_semaphore_struct(struct sembuf *sem,int semnum,int semop,int semflg)
{
sem->sem_num = semnum;
sem->sem_op = semop;
sem->sem_flg = semflg;
}
int del_semaphore(int semid)
{
#if 1
return semctl(semid,0,IPC_RMID);
#endif
}
int main(int argc,char **argv)
{
char buffer[MAX_CANON],*c;
int i,n;
int semid,semop_ret,status;
pid_t childpid;
struct sembuf semwait,semsignal;
if((argc != 2) || ((n = atoi(argv[1]))<1) )//把命令行参数中文件名后第一个字符串转为整数
{
fprintf(stderr,"Usage:%s number \n\a",argv[0]);
exit(1);
}
if((semid = semget(IPC_PRIVATE,1,PREMS)) == -1)
{
fprintf(stderr,"[%d]:Acess Semsaphore Error:%s\n\a",getpid(),strerror(errno));
exit(1);
}
init_semaphore_struct(&semwait,0,-1,0);
init_semaphore_struct(&semsignal,0,1,0);
if(semop(semid,&semsignal,1) == -1)
{
fprintf(stderr,"[%d]:Increment Semaphore Error:%s\n\a",getpid(),strerror(errno));
if(del_semaphore(semid) == -1)
{
fprintf(stderr,"[%d]:Destroy Semaphore Error:%s\n\a",getpid(),strerror(errno));
exit(1);
}
}
//create the process chain
for(i=0;i<n;i++)
{
if(childpid = fork()) break;
}
sprintf(buffer,"[i=%d]-->[proccess=%d]-->[parent=%d]-->[child=%d]\n",i,getpid(),getppid(),childpid);
c = buffer;
//request resoures and do atomic operation
while(((semop_ret = semop(semid,&semwait,1)) == -1)&&(errno==EINTR));
if(semop_ret == -1)
{
fprintf(stderr,"[%d]:Decrement Semaphore Error:%s\n\a",getpid(),strerror(errno));
}
else
{
while(*c != '\0') fputc(*c++,stderr);
//end the atomic operation,release the resoures
while(((semop_ret = semop(semid,&semsignal,1)) == -1) && (errno == EINTR));
if(semop_ret == -1)
fprintf(stderr,"[%d]:Increment Semaphore Error:%s\n\a",getpid(),strerror(errno));
}
while((wait(&status) == -1)&&(errno == EINTR));
if(i == 1)
{
if(del_semaphore(semid) == -1)
{
fprintf(stderr,"[%d]:Destory Semaphore Error:%s\n\a",getpid(),strerror(errno));
}
}
exit(0);
}