进程间通信之信号量
资源竞争
多个进程竞争同一资源时,会发生资源竞争。
资源竞争会导致进程的执行出现不可预测的结果。
临界资源
不允许同时有多个进程访问的资源, 包括硬件资源 (CPU、内存、存储器以及其他外
围设备) 与软件资源(共享代码段、共享数据结构)
临界区
多个进程共享的资源被称为临界资源,
这些资源被保护在一个临界区中,
只有进入临界区的进程才能访问临界资源。
信号量
信号量是一种进程间通信机制,用于协调对共享资源的访问。
多进程对stdout资源的竞争
//多进程对stdout资源的竞争
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
int main(){
pid_t cpid;
cpid = fork();//创建子进程
if(cpid < 0){
printf("fork error\n");//fork失败
exit(EXIT_FAILURE);//EXIT_FAILURE表示程序运行失败
} else if(cpid == 0){
//子进程
while(1){
printf("------------------------\n");
printf("C Start.\n");
sleep(1);
printf("C End.\n");
printf("------------------------\n");
}
} else{
//父进程
while(1){
printf("------------------------\n");
printf("P Start.\n");
sleep(1);
printf("P End.\n");
printf("------------------------\n");
}
wait(NULL); //等待子进程结束
}
return 0;
}
代码的输出混乱:
------------------------
P Start.
------------------------
C Start.
P End.
------------------------
C End.
------------------------
------------------------
P Start.
------------------------
C Start.
P End.
C End.
------------------------
------------------------
同步和互斥
互斥
互斥是指进程独占资源,使得其他进程无法访问该资源。
同步
同步是指进程间通信,用于协调进程的执行。
同步在互斥的基础上增加了进程对临界资源的访问顺序
进程主要的同步与互斥手段是信号量
信号量
信号量,由内核维护的整数,其值被限制为大于或等于0;
信号可以执行一下操作:
- 将信号量设置成一个具体的值;
- 在信号量当前的基础上加上一个数值;
- 在信号量当前值的基础上减上一个数值;
- 等待信号量的值为0;
一般信号量分为
- 二值信号量:一般指的是信号量值为1,可以理解为只对应一个资源
- 计数信号量:一般指的是值大于等于2,可以理解为对应多个资源
在linux系统中使用ipcs -s 查询系统中信号量
创建信号量集合
调用 semget() 函数
函数头文件:
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/types.h>
int semget(key_t key, int nsems, int semflg);
函数功能:创建一个信号量集合;
函数参数:
- key: 信号量集合的键值, 用于标识信号量集合;由ftok()函数生成;
- nsems: 信号量集合中信号量的个数;
- semflg: 信号量集合的标志位, 用于设置信号量集合的属性;
-
- IPC_CREAT: 如果key对应的信号量集合不存在, 则创建新的信号量集合;
-
- IPC_EXCL: 如果key对应的信号量集合已经存在, 则返回-1;
-
- 权限标志
函数返回值:
- 成功: 返回信号量集合的ID;
- 失败: 返回-1, 并设置errno;
//多进程对stdout资源的竞争
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <