线程的同步--信号量

来源:互联网 发布:华安股票交易软件 编辑:程序博客网 时间:2024/05/01 18:23

除了互斥锁以及条件变量,还有信号量可以来进行线程同步。信号量从本质上讲是一个非负证书计数器,通常用来控制对公共资源的访问。

相关函数(头文件 #include <semaphore.h>):
int sem_init(sem_t *sem, int pshared, unsigned value)
int sem_post(sem_t *sem)
int sem_wait(sem_t *sem)
int sem_trywait(sem_t *sem)
int sem_destroy(sem_t *sem)
当可用的公共资源增加时,调用函数sem_post()来增加信号量。只有当信号量值大于0时,函数sem_wait()才能返回,并将信号量值减1,当信号量等于0时,sem_wait()将被阻塞直到信号量的值大于0。函数sem_trywait()是sem_wait()的非阻塞版本。(当信号量从0变为1时,会唤醒一个阻塞线程,其选择机制是由线程调度策略决定的)。
对于sem_init()函数:参数一为指向信号量结构的指针,参数二若不为0则表示在该信号量进程间共享,参数三表示信号量的初始值。

程序一:线程1打印0~9之间不能被3整除的整数,线程2打印0~9之间能被3整除的数。

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <pthread.h>#include <semaphore.h>int i;sem_t sem1;void thread1(){        for(i=0; i<9; i++)        {                if(i%3 == 0)                {                        sem_post(&sem1);  //增加信号量的值                }                else                {                        printf("thread1 print i : %d\n", i);                }                sleep(1);        }        sem_post(&sem1);        pthread_exit(NULL);}void thread2(){        while(i<9)        {                if(i%3 == 0)                {                        sem_wait(&sem1);                        printf("thread2 print i : %d\n", i);                }        }        pthread_exit(NULL);}int main(){        pthread_t tid1, tid2;        int ret;        sem_init(&sem1, 0, 0);        ret = pthread_create(&tid1, NULL, (void *)thread1, NULL);        if(ret != 0)        {                perror("pthread_create");                exit(1);        }        ret = pthread_create(&tid2, NULL, (void *)thread2, NULL);        if(ret != 0)        {                perror("pthread_create");                exit(1);        }        pthread_join(tid1, NULL);        pthread_join(tid2, NULL);        sem_destroy(&sem1);        return 0;}
执行结果:
thread2 print i : 0
thread1 print i : 1
thread1 print i : 2
thread2 print i : 3
thread1 print i : 4
thread1 print i : 5
thread2 print i : 6
thread1 print i : 7
thread1 print i : 8
thread2 print i : 9

程序二:线程1,2,3,要求线程执行的顺序为3,2,1.

#include <stdio.h>#include <stdlib.h>#include <pthread.h>#include <semaphore.h>sem_t sem1;sem_t sem2;void *thread1(){        sem_wait(&sem1);        printf("This is thread 1\n");}void *thread2(){        sem_wait(&sem2);        printf("This is thread 2\n");        sem_post(&sem1);}void *thread3(){        printf("This is thread 3\n");        sem_post(&sem2);}int main(){        pthread_t tid1, tid2, tid3;        int ret;        sem_init(&sem1, 0, 0);        sem_init(&sem2, 0, 0);        ret = pthread_create(&tid1, NULL, thread1, NULL);        if(ret != 0)        {                perror("pthread_create");                exit(1);        }        ret = pthread_create(&tid2, NULL, thread2, NULL);        if(ret != 0)        {                perror("pthread_create");                exit(1);        }        ret = pthread_create(&tid3, NULL, thread3, NULL);        if(ret != 0)        {                perror("pthread_create");                exit(1);        }        pthread_join(tid1, NULL);        pthread_join(tid2, NULL);        pthread_join(tid3, NULL);        return 0;}
执行结果:
This is thread 3
This is thread 2
This is thread 1