Linux共享内存信号灯无亲缘关系进程同步示例
时间: 2023-07-02 16:07:08 浏览: 104
以下是一个使用共享内存和信号灯进行进程同步的示例,这些进程之间没有亲缘关系。
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#define SHM_SIZE 1024
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
};
int init_semaphore(int sem_id) {
union semun sem_union;
sem_union.val = 1;
return semctl(sem_id, 0, SETVAL, sem_union);
}
int semaphore_p(int sem_id) {
struct sembuf sem_b;
sem_b.sem_num = 0;
sem_b.sem_op = -1;
sem_b.sem_flg = SEM_UNDO;
return semop(sem_id, &sem_b, 1);
}
int semaphore_v(int sem_id) {
struct sembuf sem_b;
sem_b.sem_num = 0;
sem_b.sem_op = 1;
sem_b.sem_flg = SEM_UNDO;
return semop(sem_id, &sem_b, 1);
}
int main() {
key_t shm_key = 1234;
key_t sem_key = 5678;
int shm_id, sem_id;
char *shm_ptr;
// 创建共享内存
if ((shm_id = shmget(shm_key, SHM_SIZE, IPC_CREAT | 0666)) < 0) {
perror("shmget");
exit(1);
}
// 将共享内存附加到这个进程的地址空间
if ((shm_ptr = shmat(shm_id, NULL, 0)) == (char *) -1) {
perror("shmat");
exit(1);
}
// 创建信号灯
if ((sem_id = semget(sem_key, 1, IPC_CREAT | 0666)) < 0) {
perror("semget");
exit(1);
}
// 初始化信号灯
if (init_semaphore(sem_id) < 0) {
perror("semctl");
exit(1);
}
// 写入共享内存并触发信号灯
semaphore_p(sem_id);
sprintf(shm_ptr, "Hello, world!");
printf("Wrote message: %s\n", shm_ptr);
semaphore_v(sem_id);
// 从共享内存中读取数据并触发信号灯
semaphore_p(sem_id);
printf("Read message: %s\n", shm_ptr);
semaphore_v(sem_id);
// 分离共享内存
if (shmdt(shm_ptr) == -1) {
perror("shmdt");
exit(1);
}
// 删除共享内存
if (shmctl(shm_id, IPC_RMID, 0) == -1) {
perror("shmctl");
exit(1);
}
// 删除信号灯
if (semctl(sem_id, 0, IPC_RMID) == -1) {
perror("semctl");
exit(1);
}
return 0;
}
```
在这个示例中,我们使用了一个共享内存区域和一个信号灯来实现两个进程之间的同步。首先,我们创建了一个共享内存区域和一个信号灯。然后,我们使用 `semaphore_p()` 和 `semaphore_v()` 函数来加锁和解锁信号灯。
在第一个进程中,我们使用 `semaphore_p()` 函数来加锁信号灯,然后将一条消息写入共享内存区域,并使用 `semaphore_v()` 函数来解锁信号灯。在第二个进程中,我们使用 `semaphore_p()` 函数来加锁信号灯,然后从共享内存区域中读取数据,并使用 `semaphore_v()` 函数来解锁信号灯。
最后,我们分离并删除共享内存区域,并删除信号灯。
这个示例展示了如何使用共享内存和信号灯来实现进程间的同步,即使这些进程没有亲缘关系。
阅读全文