Linux中基于共享内存的多进程聊天


两个进程的代码大抵相同,只有对信号量的处理有一点区别。

第一次的提示显示有的bug😅

思路:每个进程创建一个自己的线程,这个线程根据信号量来决定是否要进入读取内容的判读,如果进入,则开始进行共享内存中是否有内容,有就取出来,没有就进行下一次的循环。

结果

在这里插入图片描述

a进程源码

#include <stdio.h>
#include <fcntl.h>           /* For O_* constants */
#include <sys/stat.h>        /* For mode constants */
#include <semaphore.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#include <signal.h>
#include <stdlib.h>
#include <pthread.h>

#define SHM_SIZE 128

char *p = NULL;
sem_t *sem1 = NULL, *sem2 = NULL;

void fun(int signo)
{
	shmdt(p); // 取消对共享空间的映射
	sem_close(sem1); // 关闭信号量,内核中没有删除
	sem_close(sem2);
	sem_unlink("zlk"); // 删除信号量
	exit(0);
	return ;
}

void *jieshou(void *arg)
{
	while(1)
	{
		// 在阻塞的时候无操作
		sem_wait(sem1);
		if(*p != 0)
		{
			//printf("收到:%s\r\n", p);
			printf("收到:%s", p);
			memset(p, 0, sizeof(SHM_SIZE));
		}
	}
}

int main(int argc, char *argv[])
{
	// 信号量部分
	sem1 = sem_open("shou", O_CREAT, 0666, 0); // 设置信号量sem1的初始化值为0
	if(SEM_FAILED == sem1) // 判断信号量是否创建成功
	{
		perror("sem_open error");
		return -1;
	}
	sem2 = sem_open("fa", O_CREAT, 0666, 0); 
	if(SEM_FAILED == sem2) // 判断信号量是否创建成功
	{
		perror("sem_open error");
		return -1;
	}
	// 共享内存部分
	key_t key = ftok(".", 22);
	if(-1 == key)
	{
		perror("ftok error");
		return -1;
	}
	int shmId = shmget(key, SHM_SIZE, IPC_CREAT | 0666); // 生成一个共享空间
	if(-1 == shmId)
	{
		perror("shmget error");
		return -1;
	}
	p = (char *)shmat(shmId, NULL, 0); // 在私有空间中建立共享内存的映射
	if((void *)-1 == p)
	{
		perror("shmat error");
		return -1;
	}
	memset(p, 0, sizeof(SHM_SIZE)); // 清空原先空间里的内容
	printf("--------zlk------------\r\n");

	// 创建一个线程,用于监听收到的信息
	pthread_t tID = -1;
    if(0 != pthread_create(&tID, NULL, jieshou, NULL))
    {
        printf("creater pthread error\r\n");
        return -1;
    }

	while(1)
	{
		signal(SIGINT, fun); // 收到Ctrl + c后调用自定义fun函数
		printf("发送:\r\n");
		fgets(p, SHM_SIZE, stdin);
		sem_post(sem2); // 使sem2加1
	}
	return 0;
}

b进程源码

#include <stdio.h>
#include <fcntl.h>           /* For O_* constants */
#include <sys/stat.h>        /* For mode constants */
#include <semaphore.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#include <signal.h>
#include <stdlib.h>
#include <pthread.h>

#define SHM_SIZE 128

char *p = NULL;
sem_t *sem1 = NULL, *sem2 = NULL;

void fun(int signo)
{
	shmdt(p); // 取消对共享空间的映射
	sem_close(sem1); // 关闭信号量,内核中没有删除
	sem_close(sem2);
	sem_unlink("zlk"); // 删除信号量
	exit(0);
	return ;
}

void *jieshou(void *arg)
{
	while(1)
	{
		sem_wait(sem2);
		if(*p != 0)
		{
			printf("收到:%s", p);
			memset(p, 0, sizeof(SHM_SIZE));
		}
	}
}

int main(int argc, char *argv[])
{
	// 信号量部分
	sem1 = sem_open("shou", O_CREAT, 0666, 0); // 设置信号量sem1的初始化值为0
	if(SEM_FAILED == sem1) // 判断信号量是否创建成功
	{
		perror("sem_open error");
		return -1;
	}
	sem2 = sem_open("fa", O_CREAT, 0666, 0); 
	if(SEM_FAILED == sem2) // 判断信号量是否创建成功
	{
		perror("sem_open error");
		return -1;
	}
	// 共享内存部分
	key_t key = ftok(".", 22);
	if(-1 == key)
	{
		perror("ftok error");
		return -1;
	}
	int shmId = shmget(key, SHM_SIZE, IPC_CREAT | 0666); // 生成一个共享空间
	if(-1 == shmId)
	{
		perror("shmget error");
		return -1;
	}
	p = (char *)shmat(shmId, NULL, 0); // 在私有空间中建立共享内存的映射
	if((void *)-1 == p)
	{
		perror("shmat error");
		return -1;
	}
	printf("--------ylx------------\r\n");
	// 创建一个线程,用于监听收到的信息
	pthread_t tID = -1;
    if(0 != pthread_create(&tID, NULL, jieshou, NULL))
    {
        printf("creater pthread error\r\n");
        return -1;
    }
	while(1)
	{
		signal(SIGINT, fun); // 收到Ctrl + c后调用自定义fun函数
		printf("发送:\r\n");
		fgets(p, SHM_SIZE, stdin);
		sem_post(sem1); // 使sem1加1
	}
	return 0;
}

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值