zoukankan      html  css  js  c++  java
  • 信号量

    一. POSIX - 信号量

    #include <semaphore.h>
    
    sem_t  sem;   ///< 信号量

    信号量,分为有名信号量 和无名信号量。

    有名信号量由sem_open/sem_close/sem_unlink创建/关闭/销毁,用于进程间通信。

    无名信号量由sem_init/sem_destroy创建/销毁,用于线程间通信。

    1. 信号量初始化

    /***********************************************************
    * @param[sem]      非命名信号量,只能被sem_destroy()销毁,
    * @param[pshared]  非0表示进程间通信信号量,但是Linux系统暂未实现这一功能(实现方式为共享内存),0表示线程间通信信号量。
    * @param[value]    信号量初始化值
    * @return          成功返回0,失败返回-1及设置错误码errno
    *//********************************************************/
    
    int sem_init(sem_t * sem, int pshared, unsigned vlaue);

    /***********************************************************
    * @param[sem]    命名信号量,只能被sem_close()关闭  有名信号量是随内核持续的,实现是以共享内存实现的.
    * @param[name]   信号量名字, 相同名字返回相同的信号量地址, name参数的构造是以  “ / ” 号开头,后面跟的字符串不能再有 “ / ” 号
    * @param[oflag]  标志位, 
              O_CREAT: 信号量不存在,就创建,参数mode,value才有效;信号量存在, 该标志位无效
              O_EXCL: 与o_CREAT连用,信号量存在,就返回失败
    * @param[mode] 创建信号量的权限, 例如:0664(八进制)
    * @param[value] 创建信号量的值 * @return 成功返回信号量的地址,失败返回SEM_FAILED及设置错误码errno *//********************************************************/ sem_t *sem_open(const char *name, int oflag);
    sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value);

    2. 信号量释放及获取

    /**********************************************************
    * @param[sem]  信号量
    * @param[abs_timeout] 真实时间 * @return 成功返回0,失败返回-1及设置错误码errno
    *//********************************************************/ int sem_post(sem_t * sem); ///< 释放信号量, 信号量值 +1 int sem_wait(sem_t * sem); ///< 获取信号量,如果信号量值为0, 会一直阻塞,否则信号量值 -1,

    int sem_trywait(sem_t * sem); ///< 尝试获取信号量,如果信号量值为0,会立即返回值,并不会阻塞

    int sem_timedwait(sem_t * sem, const struct timespec * abs_timeout); ///< 限时获取信号量,如果信号值为0,会阻塞,截止时间是abs_timeou

    3. 销毁信号量

    /***********************************************************
    * @brief       只能销毁sem_init创建的信号量
    * @param[sem]  信号量
    * @return      成功返回0, 失败返回-1,并设置错误码errno
    *//********************************************************/
    
    int sem_destroy(sem_t * sem);

    /***********************************************************
    * @brief       只能销毁sem_open创建的命名信号量
    * @param[sem]  信号量
    * @return      成功返回0, 失败返回-1,并设置错误码errno
    *//********************************************************/
    
    int sem_close(sem_t * sem);

    /***********************************************************
    * @brief       移除命名信号量和name之间的关联
    * @param[sem]  信号量
    * @return      成功返回0, 失败返回-1,并设置错误码errno
    *//********************************************************/
    
    int sem_unlink(const char *name);

    二. System V - 信号量

    #include <sys/sem.h>

    1. 创建信号量

    /**
     * @param[key]    IPC键值, 可以由ftok()生成
     * @param[nsems] 信号量集合中包含的信号量数目
     * @param[semflg] 标志位 IPC_CREAT IPC_EXCL 0664
     * @return 成功返回信号量集合标识符,错误返回-1及设置错误码errno
     */
    
    int semget(key_t key, int nsems, int semflg);

    2. 信号量操作

    /** struct sembuf */
    struct sembuf
    {
        short sem_num;    ///< 信号量, 操作信号量在信号集中的编号,编号从0开始
        short sem_op;     ///< 信号量操作, P(-1 等待信号量, 如果为0则阻塞), V(+1 释放信号量)
        short sem_flg;    ///< 操作标志位 IPC_NOWAIT(操作不满足,不会阻塞),  IPC_UNDO(不管程序是否正常结束,保证信号量值都为调用semop调用前的值)
    };
    
    /**
     * @brief
     * @param[semid]  信号量标识符
     * @param[sops]  信号量操作数组
     * @param[nops]  信号量操作数组的大小
     * @return 成功返回0,失败返回-1及设置错误码errno
     */
    
    int semop(int semid, struct sembuf *sops, size_t nops);

    3. 信号量控制

    /** union semun */
    union semun
    {
        int             val;
        struct semid_ds *buf;
        unsigned short  *array;
    };
    
    /**
     * @brief 信号量控制
     * @param[semid] 信号量标识符
     * @param[semmun]信号量集合中的顺序编号,编号从0开始
     * @param[cmd]命令
    IPC_STAT 获取信号量的semid_ds结构,结果存放在第四个参数中的buf中
    IPC_SET 设置第四个参数中的buf值(sem_perm.uid, sem_perm.gid, sem_perm.mode)为信号量标识符的值
    IPC_RMID 移除信号量,当信号量集合中所有信号量都移除后,就销毁信号量集。
    * @param[...] 第四个参数,参数结构为union semun,一般需要自定义 * @return 成功返回与cmd有关的值, 失败返回-1及设置错误码errno
    */ int semctl(int semid, int semnum, int cmd, ...);
  • 相关阅读:
    ArcGIS 10.1 如何连接数据库(转载)
    silverlight generic.xaml 包含中文 编译错误的问题
    WPF XAML之bing使用StringFormat (转)
    geoserver 知识小计
    [100天计划][1/15][1/30]开篇清单
    工作总结,给个公式,发发牢骚,继续得过
    值类型与引用类型(特殊的string) Typeof和GetType() 静态和非静态使用 参数传递 相关知识
    跑步之后的胡思乱想
    Linq To DataSet
    近期专案PM相关收获
  • 原文地址:https://www.cnblogs.com/blackandwhite/p/12545250.html
Copyright © 2011-2022 走看看