网站首页 | 站长论坛 | 免费空间申请 | 站长下载 | 站长博客 | 商业主机 | 免费空间推荐站点 | 免费空间排行榜 | 我们知道
发新话题
打印

[其它] [10-16] IPC- Sem信号量编程

本主题由 hanhan3630 于 2008-10-21 17:38 关闭

[10-16] IPC- Sem信号量编程

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);
}

TOP

收下了,多谢分享!

TOP

发新话题