线程的同步--信号量

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

相关函数(头文件 #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

你可能感兴趣的:(线程,信号量)