210226阶段三 systemV信号量

该博客记录了学习的知识点,包括线程、互斥锁、信号量等属于POSIX相关,而systemV信号量用于进程间,有P、V操作。服务器按功能分为前置和后置进程,使用两块共享内存和两个systemV信号量处理数据,避免抢夺P操作。还提及无未理解之处及当天学习收获。

一、学习的知识点

  1. 线程属于POSIX线程
  2. 互斥锁、信号量属于POSIX信号量 在进程内部使用
  3. systemV信号量: semget shmget 在进程间使用
  4. 通过ipcs查看的都是systemV系列
  5. 信号量都是对一个数字进行加一减一的操作,信号量为 0 时,若进行减一,则阻塞在此,
  6. systemV系列的P操作对信号量减1,V操作对信号量加1

服务器

根据服务器的功能分为两个进程

前置服务器(接入服务器)

接入客户端,把数据写入共享内存,通知后置服务器取数据

后置服务器(业务处理服务器)

取出数据,对数据进行处理,写入共享内存,通知前置服务器取

使用两块共享内存 两个systemV信号量 一个共享内存 存放未处理的数据,另一个共享内存存放处理后的数据。
使用两个信号量的原因是:避免后置服务器和子进程抢夺 信号量的P操作

systemV信号量

#include <sys/types.h> //man semop
#include <sys/ipc.h>
#include <sys/sem.h>
void sem_p(int sem_id)
{
	struct sembuf sops = { 0,-1,0 }; //参数1 第几个sem  参数三 标志 0为默认 阻塞
	semop(sem_id, &sops, 1); //1 操作1个信号量
}

void sem_v(int sem_id)
{
	struct sembuf sops = { 0,1,0 };
	semop(sem_id, &sops, 1);
}
int semid1 = semget(1234, 1, 0); //参数1 key 参数2 初始化的信号量个数 参数三 信号量的创建方式或权限
if (semid1 == -1)//如果打开失败 就创建
{
	semid1 = semget(1234, 1, IPC_CREAT | 0666);
}

二、上课没有听懂或者没有理解的地方

三、当天学习的收获

### 信号量集的概念 信号量集是一种用于进程间通信(Inter-Process Communication, IPC)的机制,主要用于协调多个进程对共享资源的访问。它由一组信号量组成,每个信号量表示一种特定类型的资源可用性或状态。通过 `semget` 创建或访问信号量集,并利用 `semop` 和 `semctl` 对其进行操作和控制。 #### 创建或访问信号量集 使用 `semget` 函数可以创建一个新的信号量集或者访问已有的信号量集[^2]: ```c #include <sys/ipc.h> #include <sys/sem.h> key_t key = ftok("/path/to/file", 'A'); // 生成唯一的键值 if (key == -1) { perror("ftok"); } int semid = semget(key, 1, IPC_CREAT | 0666); // 创建一个包含单个信号量的集合 if (semid == -1) { perror("semget"); } ``` 上述代码中,`ftok` 被用来生成一个唯一的键值,而 `semget` 则基于该键值创建了一个新的信号量集。参数中的 `1` 表示此信号量集中只有一个信号量。 --- #### 初始化信号量 为了设置初始值,可以通过 `semctl` 的 `SETVAL` 命令完成初始化工作: ```c #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> union semun { int val; /* Value for SETVAL */ }; union semun init; init.val = 1; // 设置第一个信号量的初值为1 if (semctl(semid, 0, SETVAL, init) == -1) { perror("semctl"); } ``` 这里定义了联合体 `semun` 来传递额外参数给 `semctl` 函数。命令 `SETVAL` 将指定索引位置上的信号量设定了一个固定数值。 --- #### 操作信号量 对于信号量的操作通常涉及等待(P操作)、释放(V操作)。这可通过调用 `semop` 实现: ```c struct sembuf sop; sop.sem_num = 0; // 指定要操作的是第几个信号量 sop.sem_op = -1; // P操作:如果当前值大于等于1,则减去;否则阻塞直到条件满足 sop.sem_flg = SEM_UNDO; if (semop(semid, &sop, 1) == -1) { perror("semop"); } /* 执行临界区代码 */ sop.sem_op = +1; // V操作:增加信号量计数器的值 if (semop(semid, &sop, 1) == -1) { perror("semop"); } ``` 以上片段展示了如何分别执行一次 P 操作以及随后的一次 V 操作来管理资源锁定与解锁过程。 --- #### 删除信号量集 当不再需要某个信号量集时,应该显式地将其移除以释放系统资源: ```c if (semctl(semid, 0, IPC_RMID) == -1) { perror("semctl(IPC_RMID)"); } ``` 这条语句会彻底销毁整个信号量集及其内部所有的信号量实例。 --- ### 总结 综上所述,Linux 下的 System V 信号量提供了一套完整的 API 接口支持复杂的同步需求场景下的应用开发。从创建到最终清理阶段都需要开发者精心设计并妥善处理各种可能发生的错误情况。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值