zoukankan      html  css  js  c++  java
  • Linux多线程编程-信号量

            在Linux中。信号量API有两组。一组是多进程编程中的System V IPC信号量。另外一组是我们要讨论的POSIX信号量。

    这两组接口类似,但不保证互换。POSIX信号量函数都已sem_开头,并不像大多数线程函数那样以pthread_开头。经常使用的有下面5个:

    #include <semaphore.h>
    int sem_init(sem_t* sem, int pshared, unsigned int value);
    int sem_destroy(sem_t *sem);
    int sem_wait(sem_t *sem);
    int sem_trywait(sem_t *sem);
    int sem_post(sem_t *sem);
    

            这些函数的第一个參数sem指向被操作的信号量。上面这些函数成功时返回0。失败返回-1并设置errno。

    sem_init函数用于初始化一个未命名的信号量(POSIX信号量API支持命名信号量,只是在该章节没有讨论)。pshared制定信号量的类型,假设其值为0,则表示这个信号量是当前进程的局部信号量。否则信号量就能够在多个进程之间共享。value制定信号量的初始值,此外初始化一个已经被初始化的信号量将导致不可预期的后果

    sem_destroy用于销毁信号量,以释放其占用的内核资源。

    假设销毁一个正在等待的信号量。则将导致不可预期的后果

    sem_wait以原子操作将信号量值减1,假设信号量的值为0,则sem_wait将被堵塞,直到该信号量值为非0值

    sem_trywaitsem_wait函数类似。只是它始终马上返回,而不论信号量是否具有非0值,相当于sem_wait的非堵塞版本号。当信号量的值为非0时。sem_trywait对信号量运行减1操作;当信号量为0时。它将返回-1并设置errno为EAGAIN

    sem_post以原子操作的方式将信号量的值加1。当信号量的值大于0时,其它正在调用sem_wait等待信号量的线程将被唤醒


    线程中使用信号量演示样例

    #include <stdio.h>
    #include <stdlib.h>
    #include <semaphore.h>
    #include <pthread.h>
    
    #define err_sys(msg) 
    	do { perror(msg); exit(-1); } while(0)
    #define err_exit(msg) 
    	do { fprintf(stderr, msg); exit(-1); } while(0)
    
    void *r1(void *arg)
    {
    	sem_t* sems = (sem_t *)arg;
    	static int cnt = 10;
    
    	while(cnt--)
    	{
    		sem_wait(sems);
    		printf("I am in r1. I get the sems.
    ");
    	}
    }
    
    void *r2(void *arg)
    {
    	sem_t* sems = (sem_t *)arg;
    	static int cnt = 10;
    
    	while(cnt--)
    	{
    		printf("I am in r2. I send the sems
    ");
    		sem_post(sems);
    		sleep(1);
    	}
    }
    
    int main(void)
    {
    	sem_t sems;
    	pthread_t t1, t2;
    	
    	printf("sems size: %d
    ", sizeof(sems));
    	/* sem_init()第二个參数为0表示这个信号量是当前进程的局部信号量。否则该信号
    	 * 就能够在多个进程之间共享 */
    	if(sem_init(&sems, 0, 0) < 0)
    		err_sys("sem_init error");
    	pthread_create(&t1, NULL, r1, &sems);
    	pthread_create(&t2, NULL, r2, &sems);
    
    	pthread_join(t1, NULL);
    	pthread_join(t2, NULL);
    	sem_destroy(&sems);
    
    	return 0;
    }
    

    參考:

            1、《Linux高性能server编程》第14章 多线程编程/信号量


  • 相关阅读:
    [iPad]PencilKit教程3、检查,修改和构造PencilKit绘图
    [iPad]PencilKit教程2、PencilKit的新功能
    [iPad]PencilKit教程1、PencilKit介绍
    为什么要谨慎使用Arrays.asList、ArrayList的subList?
    精通高并发与多线程,却不会用ThreadLocal?
    拥抱Kubernetes,再见了,SpringBoot @Scheduled
    从小公司进入大厂,我都做对了哪些事?
    总结我的Java朋友
    MySQL如何实时同步数据到ES?试试这款阿里开源的神器!
    基于Java访问数据库
  • 原文地址:https://www.cnblogs.com/gccbuaa/p/7238117.html
Copyright © 2011-2022 走看看