本文是《操作系统概念(第九版)》3.4节“进程间通信”的练习。
进程间通信主要由两种模型:
本文使用共享内存的方式实现进程间的通信
创建生产者的主要操作包括:
创建生产者的详细代码如下,可以新建一个producer.c文件,然后将代码拷贝进去:
#include
#include
#include
#include
#include
#include
#include
#include
int main() {
/* the size of shared memory object */
const int SIZE = 4096;
/* name of the shared memory object */
const char *name = "OS";
/* strings written to the shared memory */
const char *message_0 = "Hello";
const char *message_1 = "World!";
/* shared memory file descriptor */
int shm_fd;
/* pointer to shared memory object */
void *ptr;
/* create the shared memory object */
shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666);
/* configure the size of the shared memory object */
ftruncate(shm_fd, SIZE);
/* memory map the shared memory object */
ptr = mmap(0, SIZE, PROT_WRITE, MAP_SHARED, shm_fd, 0);
/* write to the shared memory object */
sprintf(ptr, "%s", message_0);
ptr += strlen(message_0);
sprintf(ptr, "%s", message_1);
ptr += strlen(message_1);
printf("Written done!");
return 0;
}
创建消费者的代码和创建消费者的代码有一些类似的地方,但是也有一些区别:
创建消费者的详细代码如下,可以新建一个consumer.c文件,然后将下列代码拷贝进去:
#include
#include
#include
#include
#include
#include
int main(){
/* the size of shared memory object */
const int SIZE = 4096;
/* name of the shared memory object */
const char *name = "OS";
/* shared memory file descriptor */
int shm_fd;
/* pointer to shared memory object */
void *ptr;
/* open the shared memory object */
shm_fd = shm_open(name, O_RDONLY, 0666);
/* memory map the shared memory object */
ptr = mmap(0, SIZE, PROT_READ, MAP_SHARED, shm_fd, 0);
/* read from the shared memory object */
printf("%s", (char *)ptr);
/* remove the shared memroy object */
shm_unlink(name);
printf("\n");
printf("Read done!\n");
return 0;
}
接下来是编译两个c文件,然后执行生产者代码,最后执行消费者代码
# 编译生产者代码
gcc -o producer producer.c -lrt
## 编译消费者代码
gcc -o consumer consumer.c -lrt
## 执行生产者代码
./producer
## 执行消费者代码
./consumer
如果有下面的报错,那么是因为引用的文件名称错误,正确的应该是 #include
(我看到的书上少了一个‘d’)
producer.c:6:10: 致命错误:sys/stath:没有那个文件或目录
#include
^~~~~~~~~~~
编译中断。
如果是下面的报错,则应该将O_RDRW
改成O_RDWR
producer.c:27:36: 错误:‘O_RDRW’ undeclared (first use in this function); did you mean ‘O_RDWR’?
shm_fd = shm_open(name, O_CREAT | O_RDRW, 0666);
^~~~~~
O_RDWR
producer.c:27:36: 附注:每个未声明的标识符在其出现的函数内只报告一次
以下报错,需要新增两个文件引用:
#include
#include
producer.c:33:22: 错误:‘PROT_WRITE’ undeclared (first use in this function); did you mean ‘S_IWRITE’?
ptr = mmap(0, SIZE, PROT_WRITE, MAP_SHARED, shm_fd, 0);
^~~~~~~~~~
S_IWRITE
producer.c:33:34: 错误:‘MAP_SHARED’未声明(在此函数内第一次使用)
ptr = mmap(0, SIZE, PROT_WRITE, MAP_SHARED, shm_fd, 0);
^~~~~~~~~~
解决办法: 在编译命令最后加 -lrt
/tmp/ccnkitBK.o:在函数‘main’中:
producer.c:(.text+0x39):对‘shm_open’未定义的引用
collect2: 错误:ld 返回 1