- 论坛徽章:
- 11
|
推荐UNIX Network Programming Volume 2 Second Edition lnterprocess ommunications by W. Richard Stevens
下面我写个例子,简单的生成者-消费者问题实现,一个程序里用父子进程方式实现生产者和消费者,分开两个进程写原理也类似,为了节省空间就偷个懒啦。共享内存保存数据,Posix基于内存的信号量同步数据访问
#include <stdio.h>
#include <semaphore.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define PATHNAME "/tmp/.what_the_hell_is_this"
typedef struct Item {
sem_t full, empty;
int data;
} Item;
void sys_err(const char* msg);
int main() {
key_t key;
pid_t pid;
int shmid;
Item* addr;
/* remove a shared memory segment from the system */
key = ftok(PATHNAME, 1);
if (key == -1)
sys_err("ftok");
shmid = shmget(key, 0, SHM_R|SHM_W);
shmctl(shmid, IPC_RMID, NULL);
/* create a new shared memory segment */
shmid = shmget(key, sizeof(Item), IPC_CREAT|IPC_EXCL|SHM_W|SHM_R);
if (shmid == -1)
sys_err("shmget");
addr = (Item*)shmat(shmid, NULL, 0);
if (addr == (Item*)-1)
sys_err("shmat");
/* initialize addr */
sem_init(&addr->full, 1, 0);
sem_init(&addr->empty, 1, 1);
shmdt(addr);
pid = fork();
if (pid > 0) { /* parent for writing */
shmid = shmget(key, 0, SHM_W);
if (shmid == -1)
sys_err("parent shmget");
addr = (Item*)shmat(shmid, NULL, 0);
if (addr == (Item*)-1)
sys_err("parent shmat");
while (1) {
sem_wait(&addr->empty);
fprintf(stdout, "parent: ");
fscanf(stdin, "%d", &addr->data);
sem_post(&addr->full);
}
} else if (pid == 0) { /* child for reading */
shmid = shmget(key, 0, SHM_R);
if (shmid == -1)
sys_err("child shmget");
addr = (Item*)shmat(shmid, NULL, 0);
if (addr == (Item*)-1)
sys_err("child shmat");
while (1) {
sem_wait(&addr->full);
fprintf(stdout, "child: %d\n", addr->data);
sem_post(&addr->empty);
}
} else {
sys_err("fork");
}
return 0;
}
void sys_err(const char* msg) {
perror(msg);
exit(0);
}
|
[lgr@localhost lab]$ gcc shm.c -lrt
[lgr@localhost lab]$ touch /tmp/.what_the_hell_is_this
[lgr@localhost lab]$ ./a.out
parent: 13
child: 13
parent: 4567
child: 4567
parent: |
|