/* Desc : gcc -o process process.c -Wall -lrt -g * watch mapfile: od -D mapfile
*/
#include <semaphore.h> #include <sys/types.h> #include <unistd.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <sys/mman.h> #include <time.h>
#define BSIZE 100
typedef struct{ int buffer[BSIZE]; sem_t lock; sem_t nready; sem_t nempty; int index; //next to put, next get is index -1
}shared_t; //gloabl variable
shared_t shared;
int get_one_item(shared_t *ptr); int put_one_item(shared_t *ptr, int pval); void err_quit(char *msg);
int main (void) { pid_t pid; int fd; //int n;
shared_t *ptr;
/* fd = open("mapfile", O_RDWR | O_CREAT, 0644); if (fd < 0) err_quit("open map file failed!"); if ((n = write(fd, &shared, sizeof(shared_t))) < 0) err_quit("write error"); ptr = mmap(NULL, sizeof(shared_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); */ ptr = mmap(NULL, sizeof(shared_t), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); if ((int)ptr == -1) err_quit("mmap error"); close(fd);
sem_init(&ptr->lock, 1, 1); /*shared between process, init-value = 1*/ sem_init(&ptr->nready, 1, 0); sem_init(&ptr->nempty, 1, BSIZE); setbuf(stdout, NULL); pid = fork(); if (pid < 0) err_quit("fork error"); else if (pid == 0){ /* child */ //sleep(2); while (1){ printf("first child %d get value: %d\n", getpid(), get_one_item(ptr)); //usleep(300*1000); } }else{ /*parent*/ int pid2 = fork(); if (pid2 < 0) err_quit("fork second process error"); else if (pid2 ==0){ while (1){ printf("sencond child %d get value: %d\n", getpid(), get_one_item(ptr)); //usleep(300*1000);
} }else{ srand(time(NULL)); int pval = 0; while(1){ pval = 1+ rand() % 1000; printf("parent put value: %d\n", put_one_item(ptr, pval)); usleep(300*1000); } } }
return 0; }
int get_one_item(shared_t *ptr) { int rval; sem_wait(&ptr->nready); sem_wait(&ptr->lock); rval = ptr->buffer[--ptr->index]; sem_post(&ptr->lock); sem_post(&ptr->nempty); return rval; }
int put_one_item(shared_t *ptr, int pval) { sem_wait(&ptr->nempty); sem_wait(&ptr->lock); ptr->buffer[ptr->index++] = pval; sem_post(&ptr->lock); sem_post(&ptr->nready); return pval; }
void err_quit(char *msg) { fprintf(stderr, "%s:%s\n", msg, strerror(errno)); exit(1); }
|