2012-1-9
信号灯:也称信号量。
1.它是不同进程间或一个给定进程内部不同线程间同步的机制。。。。。
2.信号灯得种类:
posix 有名信号灯;
posix基于内存的信号灯(无名信号灯)
3.二值信号灯:值为0或者1,只有一个资源 (使用比较多)
4.计数信号灯:值0-n之间,用来统计资源,其值代表可用资源数。。。。
5.等待操作:等待(信号灯)资源个数大于0,将其值(信号灯的值sem_op)减1,而释放进程操作相反,用来唤醒等待资源的进程或者线程。
6.信号灯结构体:semid_ds()
成员: ipc_perm()信号集可以给进程提供一个什么样的访问方式
sem_base()指向semval[0],第一个 (我们关注的是sem_base)
sem_otime 最后修改时间
sem_ctime 创建时间
7.操作信号灯集
①创建信号灯集:sem_get(key, 信号灯集的个数, 信号灯集的访问权限) 成功返回信号灯集ID
注意:多个程序中,创建时必须进行信号灯集的初始化的判断,单个的父子进程中不用判断
if ((semid = semget(key,nsems,IPC_CREAT|IPC_EXCL|0666)) < 0)
{
if (errno == EEXIST)
{
semid = semget(key,nsems,0 666);
}
}
else
{
sem_init();
}
②semctl(semid, 要修改信号的编号, SETVAL, 共用体类型) SETVAL:设置信号灯的值
注意:参数中的共用体,必须自己添加到程序中,
③sem_init(semid, num, value)封装一个信号灯集得初始化函数
{
myun.val = value;
semctl(semid, num, SETVAL, myun);
}
④sem_wait(semid, num)
{
struct sembuf mybuf;
mubuf.sem_num = num;// 要操作的信号灯的编号
mybuf.sem_op = -1; //分配资源 P操作
mybuf.sem_flg = SEM_UNDO;
sem_op(semid, &mybuf, 1); // 数字1 是要操作的信号灯的个数
}
⑤sem_op(semid, &sembuf, size_t)
参数:struct sembuf *opstr
struct sembuf
{
short sem_num; // 要操作的信号灯的编号
short sem_op; // (0 : 等待,知道信号灯的值变为0,; 1 : 释放资源 V操作; -1 : 获取资源 P操作)
short sem_flg; // (0 :阻塞,等待有有效的资源才返回,否则一直等待;IPC_NOWAIT非阻塞 ;SEM_UNDO当出现异常中断,比如ctrl+c,系统会查看进程是否占用了信号量,否则释放)
};
⑥sem_post(semid, num)
{
struct sembuf mybuf;
mubuf.sem_num = num;
mybuf.sem_op = 1; // 释放资源 V操作
mybuf.sem_flg = SEM_UNDO;
semop(semid, &mybuf, 1); // 数字1 是要操作的信号灯的个数
}
实例:用信号灯集和共享内存实现进程的互斥。。。。