Linux共享内存是Linux系统中进程间通信的一种方式,但是没有相应的同步机制,本文通过进程间的互斥锁实现一种简单的共享内存实例,仅供入门学习。
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;
pthread_mutex_t sm_mutex;
char buf[SM_BUF_SIZE];
};
#endif
</span>
<span style="font-size:18px;">sm_server.c:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/shm.h>
#include <pthread.h></span>
<span style="font-size:18px;">#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);
pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
//key = ftok( "./sm_common.h", 1 );
//printf("key: %d\n", key);
shm_id = shmget((key_t)SM_ID, sizeof(struct sm_msg), 0666|IPC_CREAT);
if(shm_id < 0)
{
perror("fail to shmget");
exit(1);
}
#if 1
shared_memory = shmat(shm_id, NULL, 0);
if (shared_memory == NULL) {
perror("Failed to shmat");
exit(1);</span>
<span style="font-size:18px;"> }
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);
}</span>
<span style="font-size:18px;"> }
ret = shmdt(shared_memory);
if (ret < 0) {
perror("Failed to shmdt");
exit(1);
}
if(shmctl(shm_id, IPC_RMID, 0) < 0)
{
perror("failed to shmctl");
exit(1);
}
#endif
return 0;
}
</span>
<span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">sm_client.c:</span></span>
<span style="font-size:18px;">#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;
// key = ftok( "./sm_common.h", 1 );
//printf("key: %d\n", key);
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);
}
}
ret = shmdt(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;
}
</span>
<span style="font-size:18px;">Makefile:
all:
gcc -o sm_server sm_server.c -lpthread
gcc -o sm_client sm_client.c -lpthread</span>
使用方法:
1. 打开终端1,运行服务端:./sm_server
2.打开终端2,运行客户端:./sm_client
3.在终端2输入字符串,在终端1可看到相应输出