进程间通信之:实验内容
(4)另外打开两个虚拟终端,分别键入"cat > in1"和"cat > (4)另外打开两个虚拟终端,分别键入"cat > in1"和"cat > in2",接着在该管道中键入相关内容,并观察实验结果。
4.实验结果
实验运行结果与第6章的例子完全相同。
$ ./pipe_select (必须先运行主程序)
SELECT CALL
select call
TEST PROGRAMME
test programme
END
end
q /* 在终端上输入’q’或’Q’立刻结束程序运行 */
$ cat > in1
SELECT CALL
TEST PROGRAMME
END
$ cat > in2
select call
test programme
end
8.7.2 共享内存实验
1.实验目的
通过编写共享内存实验,读者可以进一步了解使用共享内存的具体步骤,同时也进一步加深对共享内存的理解。在本实验中,采用信号量作为同步机制完善两个进程("生产者"和"消费者")之间的通信。其功能类似于"消息队列"中的实例,详见8.5.2小节。在实例中使用的与信号量相关的函数,详见8.3.3小节。
2.实验内容
该实现要求利用共享内存实现文件的打开和读写操作。
3.实验步骤
(1)画出流程图。
该实验流程图如图8.10所示。
图8.10 实验8.6.2流程图
(2)编写代码。
下面是共享内存缓冲区的数据结构的定义。
/* shm_com.h */
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define SHM_BUFF_SZ 2048
struct shm_buff
{
int pid;
char buffer[SHM_BUFF_SZ];
};
以下是"生产者"程序部分。
/* sem_com.h 和 sem_com.c 与"信号量"小节示例中的同名程序相同 */
/* producer.c */
#include "shm_com.h"
#include "sem_com.h"
#include <signal.h>
int ignore_signal(void)
{ /* 忽略一些信号,免得非法退出程序 */
signal(SIGINT, SIG_IGN);
signal(SIGSTOP, SIG_IGN);
signal(SIGQUIT, SIG_IGN);
return 0;
}
int main()
{
void *shared_memory = NULL;
struct shm_buff *shm_buff_inst;
char buffer[BUFSIZ];
int shmid, semid;
/* 定义信号量,用于实现访问共享内存的进程之间的互斥*/
ignore_signal(); /* 防止程序非正常退出 */
semid = semget(ftok(".", 'a'), 1, 0666|IPC_CREAT); /* 创建一个信号量*/
init_sem(semid);/* 初始值为1 */
/* 创建共享内存 */
shmid = shmget(ftok(".", 'b'), sizeof(struct shm_buff), 0666|IPC_CREAT);
if (shmid == -1)
{
perror("shmget failed");
del_sem(semid);
exit(1);
}
/* 将共享内存地址映射到当前进程地址空间 */
shared_memory = shmat(shmid, (void*)0, 0);
if (shared_memory == (void*)-1)
{
perror("shmat");
del_sem(semid);
exit(1);
}
printf("Memory attached at %X\n", (int)shared_memory);
/* 获得共享内存的映射地址 */
shm_buff_inst = (struct shared_use_st *)shared_memory;
do
{
sem_p(semid);
printf("Enter some text to the shared memory(enter 'quit' to exit):");
/* 向共享内存写入数据 */
if (fgets(shm_buff_inst->buffer, SHM_BUFF_SZ, stdin) == NULL)
{
perror("fgets");
sem_v(semid);
break;
}
shm_buff_inst->pid = getpid();
sem_v(semid);
} while(strncmp(shm_buff_inst->buffer, "quit", 4) != 0);
/* 删除信号量 */
del_sem(semid);
/* 删除共享内存到当前进程地址空间中的映射 */
if (shmdt(shared_memory) == 1)
{
perror("shmdt");
exit(1);
}
exit(0);
}
以下是"消费者"程序部分。
/* customer.c */
#include "shm_com.h"
#include "sem_com.h"
int main()
{
void *shared_memory = NULL;
struct shm_buff *shm_buff_inst;
int shmid, semid;
/* 获得信号量 */
semid = semget(ftok(".", 'a'), 1, 0666);
if (semid == -1)
{
perror("Producer is'nt exist");
exit(1);
}
/* 获得共享内存 */
shmid = shmget(ftok(".", 'b'), sizeof(struct shm_buff), 0666|IPC_CREAT);
if (shmid == -1)
{
perror("shmget");
进程间通信 实验 管道通信 Linux 操作系统 相关文章:
- 进程间通信之: 共享内存(08-13)
- 进程间通信之: 信号量(08-13)
- 《嵌入式Linux应用程序开发标准教程》(第2版)(09-30)
- 进程间通信之:消息队列(09-13)
- 进程间通信之:本章小结及思考与练习(09-13)
- 现代通信系统与DSP实验平台(07-12)