Skip to content

Instantly share code, notes, and snippets.

@kazhang
Last active October 12, 2016 21:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kazhang/e13a177c6f11315a9e9414b96aa9f698 to your computer and use it in GitHub Desktop.
Save kazhang/e13a177c6f11315a9e9414b96aa9f698 to your computer and use it in GitHub Desktop.
#include <unistd.h>
#include <semaphore.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define MAX_SIZE 1024
#define FILE_NAME "record.txt"
#define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while(0)
int main() {
sem_t *buf1_full, *buf2_full;
if((buf1_full=sem_open("sem_buf1", O_CREAT, S_IRUSR|S_IWUSR, 0))==SEM_FAILED)
handle_error("Open semaphore for buffer1");
if((buf2_full=sem_open("sem_buf2", O_CREAT, S_IRUSR|S_IWUSR, 0))==SEM_FAILED)
handle_error("Open semaphore for buffer2");
char *buf1, *buf2;
if((buf1=mmap(NULL, MAX_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0))==MAP_FAILED)
handle_error("Open shared buffer 1");
if((buf2=mmap(NULL, MAX_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0))==MAP_FAILED)
handle_error("Open shared buffer 2");
pid_t p1 = fork();
if(p1<0)
handle_error("Fork p1");
else if (p1==0) {
// child process 1
// read from file
int fd;
if((fd = open(FILE_NAME, O_RDONLY))==-1) {
handle_error("Open file");
exit(EXIT_FAILURE);
}
if(read(fd, buf1, MAX_SIZE)==-1) {
handle_error("Read file");
exit(EXIT_FAILURE);
}
// buffer 1 is full
sem_post(buf1_full);
return 0;
}
pid_t p2 = fork();
if(p2<0)
handle_error("Fork p2");
else if (p2==0) {
// child process 2
// wait until buf1 is filled by process 1
sem_wait(buf1_full);
// copy from buffer1 to buffer2
strncpy(buf2, buf1, MAX_SIZE);
// buffer2 is full
sem_post(buf2_full);
return 0;
}
pid_t p3 = fork();
if(p3<0)
handle_error("Fork p3");
else if (p3==0) {
// child process 3
// wait until buffer 2 is full
sem_wait(buf2_full);
// print the file
printf("%s", buf2);
return 0;
}
// wait until all the child processes finished
waitpid(p1, NULL, 0);
waitpid(p2, NULL, 0);
waitpid(p3, NULL, 0);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment