Chinaunix首页 | 论坛 | 博客
  • 博客访问: 631235
  • 博文数量: 1008
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 5175
  • 用 户 组: 普通用户
  • 注册时间: 2012-07-31 09:44
文章分类
文章存档

2012年(1008)

我的朋友

分类:

2012-08-01 11:15:46

原文地址:信号量 作者:luozhiyong131

#include

int semget(key_t key, int nsems, int semflg);

功能:创建一个新的旗语或取得一个已有的旗语。

返回值:成功返回旗语标识符,失败返回-1

参数:

key:系统范围内的唯一标识符,其它进程访问旗语的依据。IPC_PRIVATE告诉semget自己生成标识符,所以其它进程无法访问该旗语。使用ftok()函数获得唯一标识。

nsems:旗语个数,为1时表示单个旗语,大于1表示旗语数组,用来获取已有旗语时设为0

semflg:指令和访问权限标志,

IPC_CREAT创建新的旗语,IPC_CREAT|IPC_EXCL如果旗语存在则失败,errno设为EEXISTsemflg=0用来获取一个已有的旗语。打开权限类似open(),相当于文件的访问权限。
  1. /*
  2.  * 创建信号量
  3.  * Lzy    2011-6-16
  4.  */

  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <sys/types.h>
  8. #include <sys/ipc.h>
  9. #include <sys/sem.h>

  10. int main(void)
  11. {
  12.     int semid;        
  13.     key_t key;

  14.     key = ftok("main.c", '1');        //获取键值
  15.     if(key < 0)
  16.     {
  17.         perror("ftok");
  18.         exit(0);
  19.     }

  20.     semid = semget(key, 1, IPC_CREAT | 0666);    //创建一个信号量
  21.     if(semid < 0)
  22.     {
  23.         perror("semget");
  24.         exit(0);
  25.     }
  26.     printf("Done\n");

  27.     return 0;
  28. }

#include

int semop(int semid, struct sembuf *sops, size_t nsops);

功能:提供获取和释放旗语或旗语数组的方法。

返回值:成功返回0,否则-1

参数:

semid:旗语描述符。

sops:旗语结构(数组)指针,包含了具体操作。

struct sembuf{

    unsigned short sem_num; //对应旗语数组中的旗语,0对应第一个旗语

    short sem_op; //旗语的当前值记录相应资源目前可用数目;sem_op>0进程要释放sem_op数目的共享资源;sem_op=0用于对共享资源是否已用完的测试(调用进程将调用sleep(),直到信号量的值为0)sem_op<0进程要申请-sem_op个共享资源

    short sem_flg; //IPC_NOWAIT:无旗语可用则失败,SEM_UNDO:在进程结束时,相应的操作将被取消,如果设置了该标志位,在进程没有释放共享资源就退出时,内核将代为释放。

};

 

nsops要进行旗语操作的数量(旗语结构(数组)元素个数)

 

#include

int semctl(int semid, int semnum, int cmd, );

功能:控制旗语信息。

返回值:成功返回0(或要获取的值),否则-1

参数:

semid:旗语标识符。

semnum:旗语编号。

cmd:要进行的操作。

第四个参数,是union semun的实例,具体值依赖cmd

union semun{

    int val;

    struct semid_ds *buf;

    unsigned short *array;

}arg;

 

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <unistd.h>
  4. #include <error.h>
  5. #include <sys/types.h>
  6. #include <sys/ipc.h>
  7. #include <sys/sem.h>
  8. #include <sys/wait.h>
  9. int main()
  10. {
  11.   int semid;
  12.   pid_t pid;
  13.   key_t key;
  14.   struct sembuf lock = {0, -1, SEM_UNDO};
  15.   struct sembuf unlock = {0, 1, SEM_UNDO | IPC_NOWAIT};
  16.   int i, ret, status;
  17.   key = ftok("/home/yanyb", 'b');            /* 生成信号量的键值 */
  18.   semid = semget(key, 1, IPC_CREAT | 0666);            /* 创建一个信号量集 */
  19.   if(semid < 0)                         /* 如果信号量创建失败,输出错误信息并退出 */
  20.   {
  21.     perror("semget error");
  22.     exit(1) ;
  23.   }
  24.   ret = semctl(semid, 0, SETVAL, 1);        /* 将信号量的值设为1 */
  25.   if(ret == -1)                             /* 如果操作失败,输出错误信息并退出 */
  26.   {
  27.     perror("semctl error");
  28.     exit(1);
  29.   }
  30.   pid = fork();                            /* 创建子进程 */
  31.   if(pid < 0)                             /* 如果进程创建失败,输出错误信息并退出 */
  32.   {
  33.     printf("fork error");
  34.     exit(1);
  35.   }
  36.   if(pid == 0)                                         /* 子进程 */
  37.   {
  38.     for(i=0; i<3; i++)
  39.     {
  40.       sleep(abs((int)(3.0*rand()/(RAND_MAX+1))));         /* 休眠0~3秒 */
  41.       ret = semop(semid, &lock, 1);                        /* 申请访问共享资源 */
  42.       if(ret == -1)
  43.       {
  44.         perror("lock error");
  45.         exit(1);
  46.       }
  47.       printf("Child process access the resource.\n");            /* 开始访问共享资源 */
  48.       sleep(abs((int)(3.0*rand()/(RAND_MAX+1))));
  49.       printf("Complete!\n");
  50.       ret = semop(semid, &unlock, 1);                     /* 共享资源访问完毕 */
  51.       if(ret == -1)
  52.       {
  53.         perror("unlock error");
  54.         exit(1);
  55.       }
  56.     }
  57.   }
  58.   else                                            /* 父进程 */
  59.   {
  60.     for(i=0; i<3 ;i++)
  61.     {
  62.       sleep(abs((int)(3.0*rand()/(RAND_MAX+1))));
  63.       ret = semop(semid, &lock, 1);                     /* 申请访问共享资源 */
  64.       if(ret == -1)
  65.       {
  66.         perror("lock error");
  67.         exit(1);
  68.       }
  69.       printf("Parent process access the resource.\n");        /* 开始访问共享资源 */
  70.       sleep(abs((int)(3.0*rand()/(RAND_MAX+1))));
  71.       printf("Complete!\n");
  72.       ret = semop(semid, &unlock, 1);                     /* 共享资源访问完毕 */
  73.       if(ret == -1)
  74.       {
  75.         perror("unlock error");
  76.         exit(1);
  77.       }
  78.     }
  79.     if(pid != wait(&status))                 /* 等待子进程结束 */
  80.     {
  81.       printf("wait error");
  82.       exit(1);
  83.     }
  84.     ret = semctl(semid, 0, IPC_RMID, 0);     /* 删除信号量 */
  85.     if(ret == -1)                         /* 如果信号量删除失败,输出错误信息并退出 */
  86.     {
  87.       perror("semctl error");
  88.       exit(1);
  89.     }
  90.   }
  91.   return 0;
  92. }

 

阅读(132) | 评论(0) | 转发(0) |
0

上一篇:Kell函数

下一篇:信号集

给主人留下些什么吧!~~