Chinaunix首页 | 论坛 | 博客
  • 博客访问: 305377
  • 博文数量: 47
  • 博客积分: 2026
  • 博客等级: 大尉
  • 技术积分: 1620
  • 用 户 组: 普通用户
  • 注册时间: 2007-12-25 09:34
文章分类

全部博文(47)

文章存档

2009年(8)

2008年(39)

我的朋友

分类: LINUX

2008-11-21 15:23:09

1.       概念

信号量:代表资源数;

>0 代表可供并发进程使用的资源实体数;

=0 代表暂时无可用资源
    <0
代表等待使用资源的进程数;
    
初始设置资源数=1,用于互斥的信号量;
   
可以通过PV语操作而改变;

2.       创建信号量

       # include <sys/types.h>
       # include <sys/ipc.h>
       # include <sys/sem.h>
       int semget ( key_t key, int nsems, int semflg )

          成功返回信号ID标识,否则失败返回-1.

参数

说明

key

创建/打开信号量标识key,ftok产生,可以直接给常量

nsems

信号ID标识的一组大小。即设置几个信号量。通常为1

semflg

创建/打开方式IPC_CREATIPC_EXCL,

 
 

     key_t key,  //标识信号量的关键字,有三种方法:1、使用IPC——PRIVATE让系统产生, 2、挑选一个随机数,3、使用ftok从文件路径名中产生

3       信号量控制

 

       #include <sys/types.h>
       #include <sys/ipc.h>
       #include <sys/sem.h>
       int semctl (int semid, int semnum, int cmd, union semun arg)

参数

说明

semid

已创建的信号ID

semnum

需要控制的信号组某个信号值的下标

cmd

具体控制操作:

IPC_RMID 删除信号量ID信息

IPC_EXCL 只有在信号量集不存在时创建

IPC_SET 设置信号量的许可权  

SETVAL 设置指定信号量的元素的值为 agc.val

GETVAL 获得一个指定信号量的值

GETPID 获得最后操纵此元素的最后进程ID

GETNCNT 获得等待元素变为1的进程数
GETZCNT
获得等待元素变为0的进程数

arg

操作值的union结构

      union semun {
               int val; /* 信号量值 */
               struct semid_ds *buf; /* 信号状态结构*/
               unsigned short int *array; /*同组中信号量值 */
               struct seminfo *__buf; /* buffer for IPC_INFO */
       };

4.       信号量操作

       # include <sys/types.h>
       # include <sys/ipc.h>
       # include <sys/sem.h>
       int semop ( int semid, struct sembuf *sops, unsigned nsops )

          成功返回0,否则失败返回-1.

参数

说明

semid

已创建的信号ID

sops

具体的操作结构

nsops

信号组大小

    struct sembuf
    {
            short sem_num; /* 针对信号ID标志组中的下标的信号操作:

                                  =0 第一个信号量 */
            short sem_op; /* 对资源的使用或释放 */
            short sem_flg;
/* 操作标志:
                       IPC_NOWAIT:无资源时不等待返回,错误码为:EAGAIN
                       SEM_UNDO:若进程异常退出则由内核代为处理释放*/

    }

5       例子:

sem.c

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
 
union semun {
        int val; /* value for SETVAL */
        struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */
        unsigned short *array; /* array for GETALL, SETALL */
                                       /* Linux specific part: */
        struct seminfo *__buf; /* buffer for IPC_INFO */
        };
 
#define key 0x11000011

int P(int semid)
{
        struct sembuf sops={0,-1,SEM_UNDO};
        return (semop(semid,&sops,1));
}
int V(int semid)
{
        struct sembuf sops={0,+1,SEM_UNDO};
        return (semop(semid,&sops,1));
}
main()
{ 
        int semid,ret;
        union semun arg;
        struct sembuf semop;
 
        semid = semget(key,1,IPC_CREAT|0666);
        if (semid == -1)
        {
                printf("create semget err\n");
                return ;
        }
 
        arg.val = 1;
//创建互斥初始资源数

        ret =semctl(semid,0,SETVAL,arg);
        if (ret == -1)
        {
                printf("ctl sem err\n");
                semctl(semid,0,IPC_RMID,arg);
                return ;
        }
        ret =semctl(semid,0,GETVAL,arg);
        printf("ret af semctl =[%d]\n",ret);
//打印可用信号值

 
        P(semid); //占用资源
 
        ret =semctl(semid,0,GETVAL,arg);
        printf("ret af P=[%d]\n",ret);
//打印可用信号值

        
/*
        ...................
        */

        V(semid);
//释放资源
 
        ret =semctl(semid,0,GETVAL,arg);
        printf("ret af V =[%d]\n",ret);
//打印可用信号值
 
        semctl(semid,0,IPC_RMID,arg);
}

阅读(1873) | 评论(0) | 转发(2) |
给主人留下些什么吧!~~