在学操作系统存储管理的章节(信号量集、共享内存啥的),上机实验把我困难得啊...
看别人的资料&代码在慢慢学,在这里整理记录一下
1. 头文件
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
2. 函数semget()
- 格式(原型):int semget(key_t key, int nsems, int flag);
- 功能:创建一个新的信号量或获取一个已经存在的信号量的键值。
- 返回值:成功则返回信号量的标识码ID;失败返回-1。
3. 函数semctl()
- 格式(原型):int semctl(int semid, int semnum, int cmd, [union semun]);
- 功能:控制信号量(信号量的初始化和删除)
- 返回值:成功返回0,失败返回-1。
- 关于cmd的命令
取值 | 含义 |
---|---|
GETVAL | 返回semnum指定的信号量的semval域值 |
SETVAL | 指定semval域值为arg.val |
GETPID | 返回semnum指定信号量sempid |
GETNCNT | 返回semncnt |
GETZCNT | 返回semzcnt |
GETALL | 返回所有信号量的值,结果保存到arg.array中 |
SETALL | 通过arg.array更新所有信号量的值 |
IPC_STAT | 获取信号量集的arg.array,存入arg.buf |
IPC_SET | 将arg.buf数据结构的sem_perm.uid,sem_perm.gid,sem_perm.mode赋给sem_array,此操作仅限root、sem_perm.cuid或sem_perm.uid |
IPC_RMID | 删除指定信号量集。此操作仅限root、sem_perm.cuid或sem_perm.uid |
IPC_INFO | 获取信号量集的相关信息存放于arg.buf中 |
arg:数据类型是共同体类型semun,该类型在include/linux/sem.h中定义
- 可变参数union semum
union semun
{
int val; //使用的值
struct semid_ds *buf; //IPC_STAT、IPC_SET 使用的缓存区
unsigned short *arry; //GETALL、SETALL 使用的数组
struct seminfo *__buf; // IPC_INFO(Linux特有) 使用的缓存区
};
4. 函数semop()
- 格式(原型):int semop(int semid, struct sembuf semoparray[], size_t cnts);
- 功能:改变信号量的值——使用资源或释放资源。对信号量集标识符为semid中的一个或多个信号量进行P操作或V操作。
- sembuf semoparray[]:指向进行操作的信号量集结构体数组
- cnts:进行操作的信号量个数,常为1
- 返回值:成功返回信号量集的标识符;失败返回-1。
- 结构体sembuf:
struct sembuf{
short sem_num; //信号量集合中的信号量编号
short sem_op; //sem_op>0,信号量值加sem_op,表示进程释放控制的资源
//sem_op<0,信号量值减sem_op,若(semval-sem_op)<0,进程阻塞直到资源可用
//sem_op==0时,调用进程进入睡眠状态,直到信号值为0.
short flag; //“0”设置信号量的默认操作
//IPC_NOWAIT 设置信号量操作不等待
//SEM_UNDO 选项会让内核记录一个与调用进程相关的UNDO记录,如果该进程崩溃,则根据这个进程的UNDO记录自动恢复相应信号量的计数值
}
5.函数shmat()
- 原型:void *shmat(int shmid,const void *shmaddr,int shmflg);
- 功能:用来允许本进程访问一块共享内存的函数,与shmget()函数共同使用。
- shmaddr:
- 若shmaddr ==NULL,系统将自动选择一个合适的地址;
- 若shmaddr !=NULL 且没有指定SHM_RND,则此段连接到addr所指定的地址上;
- 若shmaddr !=0 并且指定了SHM_RND(取整),则此段连接到shmaddr -(shmaddr mod SHMLAB)所表示的地址上。
一般指定shmaddr为0,以便由内核选择地址。