sem_open sem_wait实现两个进程读写共享内存的同步的示例代码,包含非fork的进程1和进程2,两个信号量
时间: 2024-02-01 12:16:13 浏览: 26
下面是一个使用 `sem_open` 和 `sem_wait` 实现两个进程读写共享内存的同步的示例代码,包含非 fork 的进程 1 和进程 2,两个信号量。
进程 1:
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <semaphore.h>
#include <sys/mman.h>
#define SHARED_MEMORY_NAME "/shared_memory"
#define SEM_MUTEX_NAME "/sem_mutex"
#define SEM_EMPTY_NAME "/sem_empty"
#define SEM_FULL_NAME "/sem_full"
#define MAX_BUFFER_SIZE 10
typedef struct shared_memory {
int buffer[MAX_BUFFER_SIZE];
int head;
int tail;
} shared_memory_t;
int main() {
// 创建或打开共享内存
int fd = shm_open(SHARED_MEMORY_NAME, O_CREAT | O_RDWR, 0666);
if (fd < 0) {
perror("shm_open");
exit(1);
}
if (ftruncate(fd, sizeof(shared_memory_t)) < 0) {
perror("ftruncate");
exit(1);
}
shared_memory_t *shared_memory = (shared_memory_t *) mmap(NULL, sizeof(shared_memory_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (shared_memory == MAP_FAILED) {
perror("mmap");
exit(1);
}
// 创建或打开互斥锁信号量
sem_t *sem_mutex = sem_open(SEM_MUTEX_NAME, O_CREAT, 0666, 1);
if (sem_mutex == SEM_FAILED) {
perror("sem_open mutex");
exit(1);
}
// 创建或打开空信号量
sem_t *sem_empty = sem_open(SEM_EMPTY_NAME, O_CREAT, 0666, MAX_BUFFER_SIZE);
if (sem_empty == SEM_FAILED) {
perror("sem_open empty");
exit(1);
}
// 创建或打开满信号量
sem_t *sem_full = sem_open(SEM_FULL_NAME, O_CREAT, 0666, 0);
if (sem_full == SEM_FAILED) {
perror("sem_open full");
exit(1);
}
// 写入共享内存
for (int i = 0; i < MAX_BUFFER_SIZE; i++) {
sem_wait(sem_empty); // 等待空信号量
sem_wait(sem_mutex); // 等待互斥锁信号量
shared_memory->buffer[shared_memory->head] = i;
shared_memory->head = (shared_memory->head + 1) % MAX_BUFFER_SIZE;
sem_post(sem_mutex); // 发送互斥锁信号量
sem_post(sem_full); // 发送满信号量
printf("Producer put: %d\n", i);
sleep(1); // 模拟生产者速度慢
}
// 关闭和删除共享内存
if (munmap(shared_memory, sizeof(shared_memory_t)) < 0) {
perror("munmap");
exit(1);
}
if (shm_unlink(SHARED_MEMORY_NAME) < 0) {
perror("shm_unlink");
exit(1);
}
// 关闭和删除信号量
if (sem_close(sem_mutex) < 0) {
perror("sem_close mutex");
exit(1);
}
if (sem_close(sem_empty) < 0) {
perror("sem_close empty");
exit(1);
}
if (sem_close(sem_full) < 0) {
perror("sem_close full");
exit(1);
}
if (sem_unlink(SEM_MUTEX_NAME) < 0) {
perror("sem_unlink mutex");
exit(1);
}
if (sem_unlink(SEM_EMPTY_NAME) < 0) {
perror("sem_unlink empty");
exit(1);
}
if (sem_unlink(SEM_FULL_NAME) < 0) {
perror("sem_unlink full");
exit(1);
}
return 0;
}
```
进程 2:
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <semaphore.h>
#include <sys/mman.h>
#define SHARED_MEMORY_NAME "/shared_memory"
#define SEM_MUTEX_NAME "/sem_mutex"
#define SEM_EMPTY_NAME "/sem_empty"
#define SEM_FULL_NAME "/sem_full"
#define MAX_BUFFER_SIZE 10
typedef struct shared_memory {
int buffer[MAX_BUFFER_SIZE];
int head;
int tail;
} shared_memory_t;
int main() {
// 打开共享内存
int fd = shm_open(SHARED_MEMORY_NAME, O_RDWR, 0666);
if (fd < 0) {
perror("shm_open");
exit(1);
}
shared_memory_t *shared_memory = (shared_memory_t *) mmap(NULL, sizeof(shared_memory_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (shared_memory == MAP_FAILED) {
perror("mmap");
exit(1);
}
// 打开互斥锁信号量
sem_t *sem_mutex = sem_open(SEM_MUTEX_NAME, 0);
if (sem_mutex == SEM_FAILED) {
perror("sem_open mutex");
exit(1);
}
// 打开空信号量
sem_t *sem_empty = sem_open(SEM_EMPTY_NAME, 0);
if (sem_empty == SEM_FAILED) {
perror("sem_open empty");
exit(1);
}
// 打开满信号量
sem_t *sem_full = sem_open(SEM_FULL_NAME, 0);
if (sem_full == SEM_FAILED) {
perror("sem_open full");
exit(1);
}
// 读取共享内存
for (int i = 0; i < MAX_BUFFER_SIZE; i++) {
sem_wait(sem_full); // 等待满信号量
sem_wait(sem_mutex); // 等待互斥锁信号量
int value = shared_memory->buffer[shared_memory->tail];
shared_memory->tail = (shared_memory->tail + 1) % MAX_BUFFER_SIZE;
sem_post(sem_mutex); // 发送互斥锁信号量
sem_post(sem_empty); // 发送空信号量
printf("Consumer get: %d\n", value);
sleep(2); // 模拟消费者速度慢
}
// 关闭和删除共享内存
if (munmap(shared_memory, sizeof(shared_memory_t)) < 0) {
perror("munmap");
exit(1);
}
if (shm_unlink(SHARED_MEMORY_NAME) < 0) {
perror("shm_unlink");
exit(1);
}
// 关闭和删除信号量
if (sem_close(sem_mutex) < 0) {
perror("sem_close mutex");
exit(1);
}
if (sem_close(sem_empty) < 0) {
perror("sem_close empty");
exit(1);
}
if (sem_close(sem_full) < 0) {
perror("sem_close full");
exit(1);
}
return 0;
}
```