semop 是 Unix 系统调用,用于操作信号量集。信号量是一种用于保护共享资源或临界区域免受并发访问的同步原语。
以下是一个使用 semop 的简单示例,确保只有一个进程能访问临界资源:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#define SEM_NAME "/my_semaphore"
int main() {
key_t key;
int semid;
struct sembuf sops[1];
// 创建一个唯一的键
if ((key = ftok(SEM_NAME, 'R')) == -1) {
perror("ftok");
exit(1);
}
// 创建信号量集
if ((semid = semget(key, 1, IPC_CREAT | 0666)) == -1) {
perror("semget");
exit(1);
}
// 初始化信号量值为1
if (semctl(semid, 0, SETVAL, 1) == -1) {
perror("semctl");
exit(1);
}
// P操作:等待信号量变为正数
sops[0].sem_num = 0;
sops[0].sem_op = -1; // 等待
sops[0].sem_flg = SEM_UNDO; // 如果进程被终止,自动撤销操作
if (semop(semid, sops, 1) == -1) {
perror("semop");
exit(1);
}
// 临界区域开始
printf("进程 %d 进入临界区域\n", getpid());
sleep(5); // 模拟长时间操作
printf("进程 %d 离开临界区域\n", getpid());
// 临界区域结束
// V操作:增加信号量的值
sops[0].sem_num = 0;
sops[0].sem_op = 1; // 释放
sops[0].sem_flg = SEM_UNDO;
if (semop(semid, sops, 1) == -1) {
perror("semop");
exit(1);
}
// 删除信号量集
if (semctl(semid, 0, IPC_RMID) == -1) {
perror("semctl");
exit(1);
}
return 0;
}
这个示例创建了一个包含一个信号量的信号量集,并初始化其值为1。当一个进程想要进入临界区域时,它会执行 P 操作(也称为等待或减操作),这会减少信号量的值。如果信号量的值变为0或负数,进程将被阻塞,直到其他进程执行 V 操作(也称为信号或增操作)来增加信号量的值。当进程离开临界区域时,它会执行 V 操作,从而允许其他进程进入临界区域。
注意:此代码未考虑并发性和竞态条件。在实际应用中,您可能需要更复杂的同步机制来确保代码的正确性。此外,代码中的 sleep(5) 仅用于模拟长时间操作,实际应用中应根据需要调整。
标签:sops,perror,函数,临界,信号量,Unix,semop,include From: https://blog.csdn.net/slty_123/article/details/137056633