每个同步元语都可以跨进程边界使用。通过确保同步变量位于共享内存段中,并调用适当的 init() 例程,可设置元语。元语必须已经初始化,并且其共享属性设置为在进程间使用。
示例 4–17 说明了位于不同进程中的生成方和使用者的问题。主例程将与其子进程共享的全零内存段映射到其地址空间。
创建子进程是为了运行使用者,父进程则运行生成方。
本示例还说明了生成方和使用者的驱动程序。producer_driver() 可从 stdin 读取字符并调用 producer()。consumer_driver() 通过调用 consumer() 来获取字符并将这些字符写入 stdout 中。
示例 4–17 中的数据结构与示例 4–4 中所示用于条件变量示例的结构类似。两个信号分别空缓冲区和满缓冲区的数量,通过这些信号可确保生成方等待缓冲区变空,使用者等待缓冲区变满为止。
main() { int zfd; buffer_t *buffer; pthread_mutexattr_t mattr; pthread_condattr_t cvattr_less, cvattr_more; zfd = open("/dev/zero", O_RDWR); buffer = (buffer_t *)mmap(NULL, sizeof(buffer_t), PROT_READ|PROT_WRITE, MAP_SHARED, zfd, 0); buffer->occupied = buffer->nextin = buffer->nextout = 0; pthread_mutex_attr_init(&mattr); pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED); pthread_mutex_init(&buffer->lock, &mattr); pthread_condattr_init(&cvattr_less); pthread_condattr_setpshared(&cvattr_less, PTHREAD_PROCESS_SHARED); pthread_cond_init(&buffer->less, &cvattr_less); pthread_condattr_init(&cvattr_more); pthread_condattr_setpshared(&cvattr_more, PTHREAD_PROCESS_SHARED); pthread_cond_init(&buffer->more, &cvattr_more); if (fork() == 0) consumer_driver(buffer); else producer_driver(buffer); } void producer_driver(buffer_t *b) { int item; while (1) { item = getchar(); if (item == EOF) { producer(b, `\0'); break; } else producer(b, (char)item); } } void consumer_driver(buffer_t *b) { char item; while (1) { if ((item = consumer(b)) == '\0') break; putchar(item); } }