线程中的信号量和进程中的信号量的作用相同,都是用于同步操作,达到无冲突的访问共享资源的目的。但是它们也是有一定的区别的。
线程中的信号量通过参数的不同,也可以在进程间使用。
和semget() 函数创建的信号量不同,线程中的信号量可以使两个线程进行同步。
我们先看一下线程中信号量的API及其参数:
#include <semaphore.h>
1.定义信号量 sem_t sem
2.初始化信号量 sem_init(sem_t *sem,
int shared, //0表示进程内多线程使用
int val)//信号量初值
3.PV: int sem_wait(sem_t *sem) //sem--;如果小于0,阻塞
int sem_post(sem_t *sem) //sem++
4.销毁:int sem_destroy(sem_t *sem);
例子:通过两个线程分别打印12,线程1打印1,线程2打印2
代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<unistd.h>
#include<string.h>
#include<semaphore.h>
pthread_mutex_t mutex;
sem_t sem_full;
sem_t sem_empty;
void *rout1(void *arg)
{
while(1)
{
//sem_full不为0 不阻塞,sem_full--
sem_wait(&sem_full);
pthread_mutex_lock(&mutex);
printf("1");
fflush(stdout);
sleep(1);
pthread_mutex_unlock(&mutex);
//empty++
sem_post(&sem_empty);
}
return NULL;
}
void *rout2(void *arg)
{
while(1)
{
//如果屏幕为占用,即sem_empty为0 阻塞
sem_wait(&sem_empty);
pthread_mutex_lock(&mutex);
printf("2");
fflush(stdout);
sleep(1);
pthread_mutex_unlock(&mutex);
//sem_full++
sem_post(&sem_full);
}
}
int main()
{
pthread_t tid1,tid2;
//初始化sem_full为1,共享变量屏幕1
sem_init(&sem_full,0,1);
sem_init(&sem_empty,0,0);
pthread_mutex_init(&mutex,NULL);
pthread_create(&tid1,NULL,rout1,NULL);
pthread_create(&tid2,NULL,rout2,NULL);
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
pthread_mutex_destroy(&mutex);
return 0;
}
运行结果:
信号量为1,即一个屏幕。通过信号量,同步完成打印12数字。
POSIX信号量和 SystemV信号量,不同的就是:POSIX信号量可以进行同步操作。相比较一下,POSIX信号量更容易使用。