Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1885233
  • 博文数量: 496
  • 博客积分: 12043
  • 博客等级: 上将
  • 技术积分: 4778
  • 用 户 组: 普通用户
  • 注册时间: 2010-11-27 14:26
文章分类

全部博文(496)

文章存档

2014年(8)

2013年(4)

2012年(181)

2011年(303)

2010年(3)

分类: C/C++

2011-12-06 14:18:38

22.semget()
        功能:取得一组信号量.
        语法:#include
             #include
             #include
             int semget(key,nsems,semflg)
             key_t key;
             int nsems,semflg;
        说明:返回和key相关的信号量标识符.
             若以下事实成立,则与信号量标识符,与之相关的semid_ds数据结
             构及一组nsems信号量将被创建:
               . key等于IPC_PRIVATE.
               . 系统内还没有与key相关的信号量,同时(semflg&IPC_CREAT)
                 为真.
             创建时新的信号量相关的semid_ds数据结构被初始化如下:
             . 在操作权限结构,sem_perm.cuid和sem_perm.uid设置等于调用
               进程的有效UID.
             . 在操作权限结构,sem_perm.cgid和sem_perm.gid设置等于调用
               进程的有效GID.
             . 访问权限比特位sem_perm.mode设置等于semflg的访问权限比
               特位.
             . sem_otime设置等于0,sem_ctime设置等于当前系统时间.
        返回值:若调用成功,则返回一非0值,称为信号量标识符;否则返回-1.
    23.semop()
        功能:信号量操作.
        语法:#include
             #include
             #include
             int semop(semid,sops,nsops)
             int semid;
             struct sembuf *sops;
             unsigned nsops;
        说明:本系统调用用于执行用户定义的在一组信号量上操作的行为集合.
             该组信号量与semid相关.
             参数sops为一个用户定义的信号量操作结构数组指针.
             参数nsops为该数组的元素个数.
             数组的每个元素结构包括如下成员:
               sem_num;    /* 信号量数 */
               sem_op;     /* 信号量操作 */
               sem_flg;    /* 操作标志 */
             由本系统调用定义的每个信号量操作是针对由semid和sem_num指
             定的信号量的.变量sem_op指定三种信号量操作的一种:
             . 若sem_op为一负数并且调用进程具有修改权限,则下列情况之
               一将会发生:
               * 若semval不小于sem_op的绝对值,则sem_op的绝对值被减去
                 semval的值.若(semflg&SEM_UNDO)为真则sem_op的绝对值加
                 上调用进程指定的信号量的semadj值.
               * 若semval小于sem_op的绝对值同时(semflg&IPC_NOWAIT)为
                 真,则本调用立即返回.
               * 若semval小于sem_op的绝对值同时(semflg&IPC_NOWAIT)为
                 假,则本系统调用将增加指定信号量相关的semncnt值(加一),
                 将调用进程挂起直到下列条件之一被满足:
                   (1).semval值变成不小于sem_op的绝对值.当这种情况发
                       生时,指定的信号量相关的semncnt减一,若
                       (semflg&SEM_UNDO)为真则sem_op的绝对值加上调用
                       进程指定信号量的semadj值.
                   (2).调用进程等待的semid已被系统删除.
                   (3).调用进程捕俘到信号,此时,指定信号量的semncnt值
                       减一,调用进程执行中断服务程序.
             . 若sem_op为一正值,同时调用进程具有修改权限,sem_op的值加
               上semval的值,若(semflg&SEM_UNDO)为真,则sem_op减去调用
               进程指定信号量的semadj值.
             . 若sem_op为0,同时调用进程具有读权限,下列情况之一将会发
               生:
               * 若semval为0,本系统调用立即返回.
               * 若semval不等于0且(semflg&IPC_NOWAIT)为真,本系统调用
                 立即返回.
               * 若semval不等于0且(semflg&IPC_NOWAIT)为假,本系统调用
                 将把指定信号量的
                 semzcnt值加一,将调用进程挂起直到下列情况之一发生:
                   (1).semval值变为0时,指定信号量的semzcnt值减一.
                   (2).调用进程等待的semid已被系统删除.
                   (3).调用进程捕俘到信号,此时,指定信号量的semncnt值
                       减一,调用进程执行中断服务程序.
        返回值:调用成功则返回0,否则返回-1.
        例子:本例将包括上述信号量操作的所有系统调用:
             #include
             #include
             #include
             #define SEMKEY 75
             int semid;
             unsigned int count;
             /*在文件sys/sem.h中定义的sembuf结构
              * struct sembuf {
              *      unsigned short sem_num;
              *      short sem_op;
              *      short sem_flg;
              * }*/
             struct sembuf psembuf,vsembuf;   /*P和V操作*/
             cleanup()
             {
                 semctl(semid,2,IPC_RMID,0);
                 exit(0);
             }
             main(argc,argv)
             int argc;
             char *argv[];
             {
                 int i,first,second;
                 short initarray[2],outarray[2];
                 extern cleanup();
                 if (argc==1) {
                     for (i=0;i<20;i++)
                         signal(i,clearup);
                     semid=semget(SEMKEY,2,0777|IPC_CREAT);
                     initarray[0]=initarray[1]=1;
                     semctl(semid,2,SETALL,initarray);
                     semctl(semid,2,GETALL,outarray);
                     printf("sem init vals %d%d \n",
                            outarray[0],outarray[1]);
                     pause(); /*睡眠到被一软件中断信号唤醒*/
                 }
                 else if (argv[1][0]=='a') {
                     first=0;
                     second=1;
                 }
                 else {
                     first=1;
                     second=0;
                 }
                 semid=semget(SEMKEY,2,0777);
                 psembuf.sem_op=-1;
                 psembuf.sem_flg=SEM_UNDO;
                 vsembuf.sem_op=1;
                 vsembuf.sem_flg=SEM_UNDO;
                 for (count=0;;xcount++) {
                     psembuf.sem_num=first;
                     semop(semid,&psembuf,1);
                     psembuf.sem_num=second;
                     semop(semid,&psembuf,1);
                     printf("proc %d count %d\n",getpid(),count);
                     vsembuf.sem_num=second;
                     semop(semid,&vsembuf,1);
                     vsembuf.sem_num=first;
                     semop(semid,&vsembuf,1);
                 }
             }
    24.sdenter()
        功能:共享数据段同步访问,加锁.
        语法:#include
             int sdenter(addr,flags)
             char *addr;
             int flags;
        说明:用于指示调用进程即将可以访问共享数据段中的内容.
             参数addr为将一个sdget()调用的有效返回码.
             所执行的动作取决于flags的值:
             . SD_NOWAIT:若另一个进程已对指定的段调用本系统调用且还没
                 有调用sdleave(),并且该段并非用SD_UNLOCK标志创建,则调
                 用进程不是等待该段空闲而是立即返回错误码.
             . SD_WRITE:指示调用进程希望向共享数据段写数据.此时,另一
                 个进程用SD_RDONLY标志联接该共享数据段则不被允许.
        返回值:调用成功则返回0,否则返回-1.
    25.sdleave()
        功能:共享数据段同步访问,解锁.
        语法:#include
             int sdleave(addr,flags)
             char *addr;
        说明:用于指示调用进程已完成修改共享数据段中的内容.
        返回值:调用成功则返回0,否则返回-1.
    26.sdget()
        功能:联接共享数据段到调用进程的数据空间中.
        语法:#include
             char *sdget(path,flags,size.mode)
             char *path;
             int flags;
             long size;
             int mode;
        说明:本系统调用将共享数据段联接到调用进程的数据段中,具体动作
             由flags的值定义:
             . SD_RDONLY:联接的段为只读的.
             . SD_WRITE:联接的段为可读写的.
             . SD_CREAT:若由path命名的段存在且不在使用中,本标志的作用
                 同早先创建一个段相同,否则,该段根据size和mode的值进程
                 创建.对段的读写访问权限的授予基于mode给的权限,功能与
                 一般文件的相同.段被初始化为全0.
             . SD_UNLOCK:若用此标志创建该段,则允许有多个进程同时访问
                 (在读写中)该段.
        返回值:若调用成功则返回联接的段地址.否则返回-1.
阅读(870) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~