一、复习
为了实现程序的并发效果。
我们学习了线程,进程
线程:程序执行的最小单位。(轻量级进程)
内存资源共享。
进程:资源分为的最小单位。
每一个进程有独立的内存资源。
通讯问题
线程:使用全局变量进行通讯
互斥(保护临界资源):互斥锁
同步(使线程之间有先后顺序):信号量
进程:
方式:管道、信号、共享内存、消息队列、信号灯集、套接字
传统方式:有名管道、无名管道、信号
IPC通讯方式:共享内存、消息队列、信号灯集
网络通讯:套接字
2.信号灯集:
semget()创建信号灯集
semctl();设置信号灯初始值(或其他操作:删除)
semop(); ----实现PV操作
semctl()删除
semget()创建信号灯集
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>int semget(key_t key, int nsems, int semflg);
参数:
key:通过ftok得到的key值,或者使用IPC_PRIVATE创建私有消息队列
nsems:信号灯集中包含信号灯的个数
semflg: 创建消息队列权限,一般填0664 | IPC_CREAT
返回值:
成功返回信号灯集的ID,失败返回-1;
semctl();设置信号灯初始值(或其他操作:删除)
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>int semctl(int semid, int semnum, int cmd, ...(union semun arg));
参数:
semid:信号灯集标识ID
semnum:要控制的信号灯的编号,从0开始
cmd:控制命令
IPC_RMID,删除
IPC_SET,设置信号灯相关属性
。。。:可变参数 如果cmd传IPC_RMID,可变参数可以不传参。如果是IPC_SET,需要传递第四个参数。
第四个参数需要是特定的共用体
union semun {
int val; /* Value for SETVAL */
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* Array for GETALL, SETALL */
struct seminfo *__buf; /* Buffer for IPC_INFO
(Linux-specific) */
};
semop(); ----实现PV操作
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>int semop(int semid, struct sembuf *sops, size_t nsops);
参数:
semid:结构体标识id
sops:传递结构体数组的首地址,或者一个结构体的地址。
nsops:表示需要控制多少个信号灯返回值:
成功返回0,失败返回-1
struct sembuf
{
unsigned short sem_num; /* semaphore number */
short sem_op; /* semaphore operation */
short sem_flg; /* operation flags */
};
sem_num:信号灯编号
sem_op:
0:等待,直到信号灯的值变为0
1:表示V操作(释放资源)
-1:表示P造作(申请资源)
sem_flg:0 表示阻塞等待