Use semaphores and pipes
Implement A process to write content to the pipeline, B process does not read immediately, but wait for A process to write and exit before B process reads. Here, processes A and B use semaphores to achieve this effect.
We package semget semop semctl as follows
sem.h
#ifndef __SEM_H #define __SEM_H typedef union semun { int val; }Semun; int sem_init(int key,int nsems,int semval[]);//return semid void sem_p(int semid,int sems[],int size); void sem_v(int semid,int sems[],int size); void sem_del(int semid); #endif
sem.c:
#include "sem.h" #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <sys/sem.h> int sem_init(int key,int nsems,int semval[])//return semid { int semid = semget((key_t)key,0,0664); if(semid != -1) { return semid; } semid = semget((key_t)key,nsems,IPC_CREAT|0664); assert(semid!=-1); int i=0; for(;i<nsems;++i) { Semun sem; sem.val = semval[i]; semctl(semid,i,SETVAL,sem); } return semid; } void sem_p(int semid,int sems[],int size) { struct sembuf buff[size]; int i = 0; for(;i<size;++i) { buff[i].sem_num = sems[i]; buff[i].sem_op = -1; buff[i].sem_flg = SEM_UNDO; } semop(semid,buff,size); } void sem_v(int semid,int sems[],int size) { struct sembuf buff[size]; int i = 0; for(;i<size;++i) { buff[i].sem_num = sems[i]; buff[i].sem_op = 1; buff[i].sem_flg = SEM_UNDO; } semop(semid,buff,size); } void sem_del(int semid) { if(-1 == semctl(semid,0,IPC_RMID)) { printf("delete error\n"); exit(0); } }
Related code of process A:
/*================================================================ * Copyright (C) 2019 Sangfor Ltd. All rights reserved. * * File name: main.c * Created by: gaojie * Date of establishment: July 8, 2019 * Description: * ================================================================*/ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <assert.h> #include "sem.h" #include <fcntl.h> int main() { int val=0; int semid = sem_init(1234,1,&val); int fd = open("FIFO",O_WRONLY); assert(fd != -1); while(1) { printf("please input:\n"); char buff[128]={0}; fgets(buff,128,stdin); if(strncmp(buff,"end",3)==0) { break; } write(fd,buff,strlen(buff)-1); } int sem = 0; sem_v(semid,&sem,1); close(fd); }
Related code of process B
/*================================================================ * Copyright (C) 2019 Sangfor Ltd. All rights reserved. * * File name: mainb.c * Created by: gaojie * Date of establishment: July 8, 2019 * Description: * ================================================================*/ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <assert.h> #include <fcntl.h> #include "sem.h" int main() { int val = 0; int semid = sem_init(1234,1,&val); int fd = open("FIFO",O_RDONLY); printf("open FIFO success\n"); assert(-1!=fd); int sem = 0; sem_p(semid,&sem,1); char buff[1024]={0}; int n =read(fd,buff,1023); if(n<=0) { printf("error\n"); exit(0); } printf("data length = %d \n",strlen(buff)); printf("%s\n",buff); close(fd); }
If we comment out the semaphore related operations of process A and process B
It can be seen that process B receives and exits after our process A has been input once. Since the pipeline must have A section of reading and A section of writing before it can work normally, after B exits, process A exits with the exit of B.
But we add in the semaphore "blocking" the data received by process B. at this time, process B must wait for process A to release the critical area resources before entering the critical area code.