Linux多进程间通信——共享内存实现聊天室程序

本文介绍了一个使用Linux共享内存实现的简单聊天室程序,涉及两个进程之间的通信。程序通过创建两个共享内存区域和信号量进行读写同步,其中一个进程负责接收并显示消息,另一个进程负责输入消息。程序展示了如何在C语言中实现进程间通信的基本步骤,包括创建信号量、共享内存以及读写操作。
摘要由CSDN通过智能技术生成

Linux多进程间通信——共享内存实现聊天室程序

上一讲我们用共享内存实现了进程间的简单通信,一个进程写,一个进程读,我们这次增加一点难度,创建两块共享内存,来实现一个简单的聊天室程序。

先自己动手做一下,再来看源码。

下面给出源码,一共有四个进程,两两实现通信,互相收发消息

shmmutexRW_Server.c代码如下:

#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
int main(){
	sem_t *sem_1;//定义信号量
	sem_t *sem_2;
	int shmid[2];//共享内存ID

	struct Student{
		char name[20];
		int age;
		int number;
	};
	struct Student *shmaddr[2];
	//创建信号量来实现读写锁,读写不能同时进行
	sem_1 = sem_open("sem_1", O_CREAT, 0644, 1);
	sem_2 = sem_open("sem_2", O_CREAT, 0644, 1);
	
	//创建子进程
	pid_t pid;
	pid = fork();
	
	if(pid < 0){
		perror("cannot fork!\n");
		return -1;
	}
	else if(pid == 0){
		//子进程,用共享内存shmaddr[0]来接收shmMutexRW_Server.c子进程的消息
		key_t shmkey;
		shmkey = ftok("/etc", 0);//创建共享内存的标识
		shmid[0] = shmget(shmkey, 100, 0666|IPC_CREAT);
		if(shmid[0] == -1){
			printf("shmget failed\n");
			exit(0);
		}
		shmaddr[0] = (struct Student*)shmat(shmid[0], 0, 0);
		if(shmaddr[0] == (struct Student*)-1){
			printf("shmat failed\n");
			exit(0);
		}
		//开始读此进程中的数据并显示
		shmaddr[0]->age = 0;
		while(1){
			sem_wait(sem_1);
			if(shmaddr[0]->age > 0){
				printf("子进程Server读到共享内存中的数据:姓名:%s\n", shmaddr[0]->name);
				shmaddr[0]->age--;
			}
			sem_post(sem_1);
		}
		sem_close(sem_1);
		if(shmdt(shmaddr[0]) == -1) printf("shmdt failed\n");
		if(shmctl(shmid[0], IPC_RMID, NULL) == -1) printf("shmctl failed\n");	
	}
	else{
		//父进程,向共享内存shmaddr[1]中写入数据,供shmMutexRW_Server.c的父进程读数据
		//创建共享内存shmaddr[1]
		key_t shmkey1 = ftok("/bin", 0);
		shmid[1] = shmget(shmkey1, 100, 0666|IPC_CREAT);
		if(shmid[1] == -1){
			printf("shmget failed\n");
			exit(0);
		}
		shmaddr[1] = (struct Student*)shmat(shmid[1], 0, 0);
		if(shmaddr[1] == (struct Student*)-1){
			printf("shmat failed\n");
			exit(0);
		}
		shmaddr[1]->age = 0;//这里很关键,还是信号量的赋初值很关键?
		while(1){
			sem_wait(sem_2);
			memset(shmaddr[1]->name,  0, 20);	
			printf("写进程:请输入姓名(不超过20字符)到共享内存:\n");
			if(fgets(shmaddr[1]->name, 20, stdin) == NULL){
				perror("fgets failed\n");
				sem_post(sem_2);
				break;
			}
			shmaddr[1]->age++;
			sem_post(sem_2);
			sleep(1);
		}
		sem_close(sem_2);
		if(shmdt(shmaddr[1]) == -1){
			printf("shmdt failed\n");
		}
		if(shmctl(shmid[1], IPC_RMID, NULL)){
			printf("shmctl failed\n");
		}	
	}
	sem_unlink("shmaddr[0]_RW");
	sem_unlink("shmaddr[1]_RW");
	return 0;
}

这里shmmutexRW_Client.c的源码我就不再给出了,读者们可以根据上一讲的内容来自己实现一下。

程序运行的效果如下:

请添加图片描述

完整源码我放在公众号河边小乌龟爬中了,需要的自取,回复共享内存聊天室即可获得。

我是河边小乌龟爬,学习嵌入式软件开发路上的一名小学生,欢迎大家相互交流哇。公众号:河边小乌龟爬。

团队提供丰富嵌入式项目学习,以及嵌入式方向毕业设计指导,欢迎咨询。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

河边小乌龟爬

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值