system V信号量
2015-10-18 11:16
573 查看
相对于Posix信号量,system V信号量提供了更为丰富的操作,如Posix信号量一次只能增减1,而system V则没有此限制;另外,可以用一个函数(semget)创建一组(多个)信号量,而Posix信号量一次只能创建一个;因此可用其模拟Posix信号量。功能丰富的同时也决定了System V信号量的复杂性。
1) 相关函数:
头文件:<sys/sem.h>
创建或打开:semget
操作:semop 包含的操作有:挂出和等待(对应增减的信号量只可以大于1)
控制操作:semctl,主要用于初始化信号量集中信号量的初始值、获取相关状态(信号量值,semid_ds结构,相关操作的线程数信息)、删除、设置uid、gid、sem_perm.mode(读写权限)
更详细的说明可以查看man手册,如man semget将获取函数的相关说明。
2) 要点
需要注意的是,由于System V信号量的创建和初始化工作是分两步进行的(不像Posix信号量创建和初始化是一个原子操作),这就需要相关的同步工作,确保A进程创建的信号量在被其他进程使用前已经被初始化。
原理:当semget创建一个新的信号量集时,其semid_ds结构的sem_otime成员保证被置为0,因此,其他线程在成功调用semget打开信号量后,必须以IPC_STAT命令调用semctl.然后等待sem_otime变为非零值,这时就可以断定信号量已被初始化。
代码表述如下:
#define MSG_W(0400)
#define MSG_R(0200)
//permission formessage queues 660
#defineSVMSG_MODE (MSG_R | MSG_W | MSG_R >> 3 | MSG_W >> 3)
#define MAX_TIMES100
union senum {
int val;
struct semid_ds *buf;
usigned short*array;
};
int semid;
int oflag =IPC_CREAT | IPC_EXEL | SVSEM_MODE;
union senum arg;
struct semid_ds seminfo;
if (semid = semget(ftok(“/tmp/sem1”),1, oflag) >= 0)
{
// create successed, now set theinitial value
arg.val = 1;
semctl(semid, 0, SETVAL, arg);
}
else if (EEXIST== errno)
{
semid = semget(ftok(“/tmp/sem1”), 1,oflag);
arg.buf = &seminfo;
for (int i = 0; i < MAX_TIMES; i++)
{
semctl(semid, 0, IPC_STAT,arg);
if (arg.buf->sem_otime !=0)
{
//here indicates initialsuccessed
break;
}
sleep(1);
}
if (MAX_TIMES == i)
{
//aftertry MAX_TIMES, the semaphore still no been initialized
}
}
1) 相关函数:
头文件:<sys/sem.h>
创建或打开:semget
操作:semop 包含的操作有:挂出和等待(对应增减的信号量只可以大于1)
控制操作:semctl,主要用于初始化信号量集中信号量的初始值、获取相关状态(信号量值,semid_ds结构,相关操作的线程数信息)、删除、设置uid、gid、sem_perm.mode(读写权限)
更详细的说明可以查看man手册,如man semget将获取函数的相关说明。
2) 要点
需要注意的是,由于System V信号量的创建和初始化工作是分两步进行的(不像Posix信号量创建和初始化是一个原子操作),这就需要相关的同步工作,确保A进程创建的信号量在被其他进程使用前已经被初始化。
原理:当semget创建一个新的信号量集时,其semid_ds结构的sem_otime成员保证被置为0,因此,其他线程在成功调用semget打开信号量后,必须以IPC_STAT命令调用semctl.然后等待sem_otime变为非零值,这时就可以断定信号量已被初始化。
代码表述如下:
#define MSG_W(0400)
#define MSG_R(0200)
//permission formessage queues 660
#defineSVMSG_MODE (MSG_R | MSG_W | MSG_R >> 3 | MSG_W >> 3)
#define MAX_TIMES100
union senum {
int val;
struct semid_ds *buf;
usigned short*array;
};
int semid;
int oflag =IPC_CREAT | IPC_EXEL | SVSEM_MODE;
union senum arg;
struct semid_ds seminfo;
if (semid = semget(ftok(“/tmp/sem1”),1, oflag) >= 0)
{
// create successed, now set theinitial value
arg.val = 1;
semctl(semid, 0, SETVAL, arg);
}
else if (EEXIST== errno)
{
semid = semget(ftok(“/tmp/sem1”), 1,oflag);
arg.buf = &seminfo;
for (int i = 0; i < MAX_TIMES; i++)
{
semctl(semid, 0, IPC_STAT,arg);
if (arg.buf->sem_otime !=0)
{
//here indicates initialsuccessed
break;
}
sleep(1);
}
if (MAX_TIMES == i)
{
//aftertry MAX_TIMES, the semaphore still no been initialized
}
}
相关文章推荐
- Linux socket 初步
- linux lsof详解
- linux 文件权限
- Linux 执行数学运算
- 10 篇对初学者和专家都有用的 Linux 命令教程
- Linux 与 Windows 对UNICODE 的处理方式
- Ubuntu12.04下QQ完美走起啊!走起啊!有木有啊!
- 解決Linux下Android开发真机调试设备不被识别问题
- 运维入门
- 运维提升
- Linux 自检和 SystemTap
- Ubuntu Linux使用体验
- c语言实现hashmap(转载)
- Linux 信号signal处理机制
- linux下mysql添加用户
- Scientific Linux 5.5 图形安装教程
- 基于 Linux 集群环境上 GPFS 的问题诊断
- 谁是桌面王者?Win PK Linux三大镇山之宝
- vivi下重新调整分区