进程间通信-共享内存-互斥锁同步(一)

12 篇文章 0 订阅

代码参考网上其他人的,分三个文件

sm_common.h

#ifndef __SM_COMMON_H__
#define __SM_COMMON_H__
 
#include <pthread.h>
 
#define SM_BUF_SIZE 1024
#define SM_ID 0x1122
 
struct sm_msg
{
	int flag;//标志位,0代表在写,1表示在读
	pthread_mutex_t sm_mutex;//互斥锁
	char buf[SM_BUF_SIZE];//存放的数据
};
 
 
#endif

sm_server.c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/shm.h>
#include <pthread.h>

#include "sm_common.h"

int main(void)
{
	int shm_id = -1;
	int ret = -1;
	int key = -1;
	int running = 1;
	struct sm_msg *msg = NULL;
	void *shared_memory = NULL;
	pthread_mutexattr_t attr;
 
	pthread_mutexattr_init(&attr);//init mutex lock
	pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);//set mutex lock ,other procecc can use

	shm_id = shmget((key_t)SM_ID, sizeof(struct sm_msg), 0666|IPC_CREAT);
	if(shm_id < 0)
	{
		perror("fail to shmget");
		exit(1);
	}

	shared_memory = shmat(shm_id, NULL, 0);
	if (shared_memory == NULL) 
	{
		perror("Failed to shmat");
		exit(1);	
	}
 
	msg = (struct sm_msg *)shared_memory;
	msg->flag = 0;
	pthread_mutex_init(&msg->sm_mutex, &attr);
 
	while (running) 
	{
		pthread_mutex_lock(&msg->sm_mutex);
		if (msg->flag == 1) 
		{
			printf("Read message: %s\n", msg->buf);
			msg->flag = 0;
			pthread_mutex_unlock(&msg->sm_mutex);
			if (strncmp(msg->buf, "exit", 4) == 0) 
			{
				running = 0;
			}
		}
		else 
		{
			printf("No available data to read, sleep...\n");
			pthread_mutex_unlock(&msg->sm_mutex);
			sleep(2);
		}
	}
 
	ret = shmdt(shared_memory);//disconnect shared memory
	if (ret < 0) 
	{
		perror("Failed to shmdt");
		exit(1);
	}
 
	if(shmctl(shm_id, IPC_RMID, 0) < 0)//ctrol shared memory ,rm 
	{
		perror("failed to shmctl");
		exit(1);
	}

	return 0;
}

sm_client.c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/shm.h>
#include <pthread.h>
 
#include "sm_common.h"
 
int main(void)
{
	int shm_id = -1;
	int ret = -1;
	int key = -1;
	int running = 1;
	struct sm_msg *msg = NULL;
	void *shared_memory = NULL;//共享内存原始地址
	shm_id = shmget((key_t)SM_ID, sizeof(struct sm_msg), 0666|IPC_CREAT);
	if(shm_id < 0)
	{
		perror("fail to shmget");
		exit(1);
	}
 
	shared_memory = shmat(shm_id, NULL, 0);//共享内存分配地址
	if (shared_memory == NULL) 
	{
		perror("Failed to shmat");
		exit(1);
	}
 
	msg = (struct sm_msg *)shared_memory;//转化为结构体,并把指针地址赋值给结构体指针
	char buf[32];
	while (running) 
	{
		printf("wait lock\n");
		pthread_mutex_lock(&msg->sm_mutex);
		printf("get lock\n");
		if(msg->flag == 1) 
		{
			printf("Wait for other process's reading\n");
			pthread_mutex_unlock(&msg->sm_mutex);
			sleep(2);
		}
		else 
		{
			printf("Please input data\n");
			fgets(buf, 32, stdin);
			printf("Write msg: %s\n", buf);
			strncpy(msg->buf, buf, sizeof(buf));		
			msg->flag = 1;
			if (strncmp(msg->buf, "exit", 4) == 0) 
			{
				running = 0;
			}
			pthread_mutex_unlock(&msg->sm_mutex);//unlock
		}
	}
 
	ret = shmdt(shared_memory);//disconnect shared memory
	if (ret < 0) 
	{
		perror("Failed to shmdt");
		exit(1);
	}
	
#if 0 //Do thsi in server.
	if(shmctl(shm_id, IPC_RMID, 0) < 0)
	{
		perror("failed to shmctl");
		exit(1);
	}
#endif
	return 0;
}

1、共享内存是最快的IPC方式,唯一缺点是同步机制得添加,而且,读完数据,数据还存在。

2、这个例子有个标志位,读完一次就不能再读,写完一次就不能再写,除非已经读过。

3、对于数据更新过多、过快机制没有。我要写入数据很多,一次写不满,分多次,一定时间后没有人来读,数据满后就要清掉,继续写。

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值