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

     

    信号量是一种用于提供不同进程或统一进程间不同线程同步手段的原语,其操作包括P操作(将信号量的值-1)和V操作(将信号量值+1),其典型应用场景为多个生成者和多个消费者的情况,也用于控制多个进程的并发数。POSIX信号量包含两种类型:

    a)      POSIX有名信号量:使用PosixIPC名字标识

    相关函数:

    头文件 #include<semaphore.h>

    创建:sem_t*sem_open(const char *name, into flag, /mode_t mode, unsigned int value */);

    成功返回指向信号量的指针,若出错则为SEM_FAILED(注意不为-1);value用于指定信号量的初始值,但该值不超过SEM_VALUE_MAX ;其余用法同mq_open

    关闭:int sem_close(sem_t*sem);     //成功返回0,若出错则为-1

    关闭一个信号量并没有将它从系统中删除,即POSIX有名信号量至少具有随内核的持续性,即使当前没有进程打开着某个信号量,它的值仍然保持。

    删除:int sem_unlink(constchar *name);   //若成功则为0,若出错则为-1

    等待(P操作):int sem_wait(sem_t *sem);  //阻塞形式,成功返回0,失败为-1;若被信号中断,错误码为EINTR

             intsem_trywait(sem_t *sem);  //非阻塞形式,成功返回0,失败为-1;当无法立即获取信号量时返回EAGAIN错误

    挂出(V操作):int sem_post(sem_t *sem);       //成功返回0,失败-1

    取值:intsem_getvalue(sem_t *sem, int *valp);   //成功返回0,失败-1;成功则信号量的值存放与valp指向的变量中,若该信号量当前已上锁,则*valp为0或者负数,负数表示等待该信号量解锁的进程数为-*valp。有些平台上的实现是信号量*valp不会为负值。

    p.s:在内核中,创建信号量的默认路径是/dev/shm,所以以/tmp/semname创建信号量会出错,解决办法是以semname作为参数创建信号量,将创建/dev/shm/sem.semname文件


    b)      POSIX基于内存的信号量:存放在内存中或共享内存中(存放在非共享内存中的只能用于线程同步)

    相关函数:

    创建和初始化信号量:intsem_init(sem_t *sem, int shared, unsigned int value); 

    sem参数执行应用程序必须分配的sem_t变量,如果shared 为0,那么待初始化的信号量是同一进程间各线程共享的,否则该信号量是在进程间共享的。当shared为非零时,该信号量必须存在某种类型的共享内存中,而要使用它的各个进程都需要能访问该共享内存。

    返回值:失败返回-1,成功返回0

    摧毁信号量:int sem_destroy(sem_t*sem);  //失败返回-1,成功返回0

    有名信号量和无名信号量两者的几点区别:

    1、  有名信号量具有随内核的持续性,而无名信号量至少具有随进程的持续性,然而其真正的持续性却取决于存放信号量的内存区的类型,只有含有某个基于内存信号量的内存区保持有效,该信号量就一直存在。

    2、  由于上述的区别也导致了删除有名信号量用sem_unlink(类似删除文件unlink),摧毁无名信号量用sem_destroy(有点相当于sem_close+sem_unlink;若不调用则随进程或共享内存区结束)

    3、  其余的挂出、等待和取值操作一致

    最后,总结一下信号量与互斥量,条件变量的差异:

    1)      互斥锁总是由给它上锁的线程解锁,信号量的挂出却不必由执行过它的等待操作的同一线程执行

    2)      互斥锁要么被锁住,要么被解开(类似于二值信号量)

    3)      信号量的挂出(post——+1)操作总是被记住,反映在信号量的值上;然而当向一个条件变量发送信号时,如果没有线程等待在该条件变量上,那么信号将丢失

    4)      互斥量和条件变量多用于线程同步,但也可用于进程间;信号量的意图在于进程间同步,但也可用于线程间。

    5)      在各种同步技巧中(互斥量+条件变量、读写锁、信号量),能够从信号处理程序中安全调用的唯一函数是sem_post

    6)      互斥锁是为上锁而优化的,条件变量是为等待而优化的,信号量既可用于上锁也可用于等待,因而可能导致更多的开销和更高的复杂性;使用时结合实际

  • 相关阅读:
    java学习day08--面向对象--继承+方法重写+static关键字
    java学习day07--面向对象--封装+this关键字+构造器
    java学习day06-面向对象--类和对象
    依赖管理
    NSQ消息队列
    logger包
    time包
    fmt包
    Go_Protobu
    Go_性能优化
  • 原文地址:https://www.cnblogs.com/OpenLinux/p/5020695.html
Copyright © 2011-2022 走看看