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可看到相应输出