狐狸梦见乌鸦

当坚持成为一种习惯,目标将不在遥远```
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

信号灯--学习笔记

Posted on 2012-01-09 17:35  灬啊U  阅读(372)  评论(0编辑  收藏  举报

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 是要操作的信号灯的个数

}

 

实例:用信号灯集和共享内存实现进程的互斥。。。。