tag 标签: 信号互斥编程

相关博文
  • 热度 17
    2015-3-9 15:31
    1422 次阅读|
    0 个评论
    信号量(又名:信号灯)与其他进程间通信方式不大相同,主要用途是保护临界资源(进程互斥)。进程可以根据它判定是否能够访问某些共享资源。除了用于访问控制外,还可用于进程同步。 信号量的分类: 二值信号灯:信号灯的值只能取0或1 计数信号灯:信号灯的值可以取任意非负值。 信号量的实质:1、数字  2、操作,包括释放和获取两种情况。   8.1   创建 /   打开信号量集合 8.1.1   函数名     semget 8.1.2   函数原形     int semget(key_t key, int nsems, int sem***); 8.1.3   函数功能     获取信号量集合的标识符 8.1.4   所属头文件     sys/types.h  sys/ipc.h  sys/sem.h 8.1.5   返回值    成功:返回信号量集合的标识符  失败:-1  8.1.6   参数说明      key:键值  sem***:标志,可以取IPC_CREAT  nsems:创建的这个信号量集合里面包含的信号量的数目 8.1.7   范例代码   8.2   操作信号量 8.2.1   函数名     semop 8.2.2   函数原形     int semop(int semid, struct *sops, unsigned nsops, struct timespec *timeout); 8.2.3   函数功能     操作信号量集里面的信号量 8.2.4   所属头文件     sys/types.h  sys/ipc.h  sys/sem.h 8.2.5   返回值     成功:返回0  失败:返回-1 8.2.6   参数说明     semid:要操作的信号量集合的标识符  nsops:要操作多少个信号量  sops:堆信号量执行什么样的操作,实则sops包含了下面这个结构体:其中sem_num:指定了是信号量集合的第几个信号量。sem_op:若sem_op为n。n0则表示释放了n个信号量。n0则表示获取了n个信号量 8.3   信号量的控制 8.3.1   函数名     semctl 8.3 .2   函数原形     int semctl(int semid, int semnum, int cmd, ...); 8.3 .3   函数功能     控制信号量 8.3 .4   所属头文件     sys/types.h  sys/ipc.h  sys/sem.h 8.3 .5   返回值     成功:根据cmd返回不同的非负值  失败:-1 8.3 .6   参数说明     semid:信号量集合的标识符 semnum:信号量集合的哪个信号量   cmd:相应的控制命令(GETVAL:返回成员semnum的semval值, SETVAL:设置成员semnum的semval值。该值由arg.val指定)。   8.4   获取key值 8.4.1   函数名     ftok 8.4 .2   函数原形     key_t ftok(const char *pathname, int proj_id); 8.4 .3   函数功能      将路径名和项目标识符转化为一个进程间信号量通信的key值 8.4 .4   所属头文件     sys/types.h  sys/ipc.h 8.4 .5   返回值    成功:key值将被返回  失败:-1  8.4 .6   参数说明     pathname:路径名  proj_id:自定义的数字id   小实验:假设有这样的场景:数学课代表A要在公示栏上写“math cancel”这样一个通知。当他写完“math”后,电话铃响了。然后出去接了个电话。正在这时英语课代表B也要写通知,通知内容是“English exam”。这时公示栏上的内容是“math English exam”。B写完后,A又不管三七二十一的写上了“cancel”。这时黑板上的内容为“math English exam cancel”。从而引起了歧义。代码如下:   astudent.c: #includestdio.h #includesys/types.h #includesys/stat.h  #includefcntl.h int main() {      int fd;      fd = open("/home/board.txt",O_RDWR|O_APPEND);//读取txt文件      write(fd, "math", 5);      sleep(3);      write(fd, " cancel", 7);      close(fd);      return 0; } bstudent.c: #includestdio.h #includesys/types.h #includesys/stat.h  #includefcntl.h int main() {      int fd;      fd = open("/home/board.txt",O_RDWR|O_APPEND);//读取txt文件      write(fd, "English exam", 13);      return 0; } 公示栏上的内容为下图:   那么,怎样消除这样的问题呢?我们可以看出这两个事件是互斥的。我们可以通过设置一个信号量来解决。当A开始写通知的时候生成一个标志位。直至A写完通知,标志位状态改变,B开始写通知。   #includestdio.h #includesys/types.h   #includesys/stat.h    #includefcntl.h #includesys/types.h    #includesys/ipc.h    #includesys/sem.h int main() {      int fd = 0;      int semid;      key_t key;      struct sembuf sops;      int ret;      key = ftok("/home", 1);      semid = semget(key, 1, IPC_CREAT);      semctl(semid, 0, SETVAL, 1);      fd = open("/home/board.txt",O_RDWR|O_APPEND);//读取txt文件             sops.sem_num = 0;      sops.sem_op = -1;      semop(semid, sops, 1);             write(fd, "math", 5);      sleep(10);      write(fd, " cancel", 7);      sops.sem_num = 0;      sops.sem_op = 1;      semop(semid, sops, 1);      close(fd);      return 0; }   #includestdio.h #includesys/types.h   #includesys/stat.h    #includefcntl.h #includesys/types.h    #includesys/ipc.h    #includesys/sem.h int main() {      int fd = 0;      int semid;      key_t key;      struct sembuf sops;      int ret;      key = ftok("/home", 1);      semid = semget(key, 1, IPC_CREAT);      fd = open("/home/board.txt",O_RDWR|O_APPEND);//读取txt文件      sops.sem_num = 0;      sops.sem_op = -1;      semop(semid, sops, 1);             write(fd, "English exam", 13);      sops.sem_num = 0;      sops.sem_op = 1;      semop(semid, sops, 1);      close(fd);      return 0; }