POSIX信号量和System V信号量作用相同,都是用于同步操作,达到无冲突的访问共享资源,但是POSIX可以用于线程间同步。该类函数存放在semaphore.h头文件中。
1、初始化信号量
int sem_init(sem_t *sem, int pshared, unsigned int value);
参数:
(1)pshared:0表示线程间共享,非零表示进程间共享。
(2)value:信号量初始值。
2、销毁信号量
int sem_destroy(sem_t *sem);
3、等待信号量
(1)功能:等待信号量,会将信号量的值减1。
(2)函数原型:int sem_wait(sem_t *sem);
4、发布信号量
(1)功能:发布信号量,表示资源使用完毕,可以归还资源了。将信号量值加1。
(2)函数原型:int sem_post(sem_t *sem);
【例】
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<semaphore.h>
#include<pthread.h>
#include<string.h>
#include<errno.h>
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
}while(0)
#define CONSUMERS_COUNT 3
#define PRODUCERS_COUNT 3
#define BUFFSIZE 10
int g_buffer[BUFFSIZE];
unsigned short in = 0;
unsigned short out = 0;
unsigned short produce_id = 0;
unsigned short consume_id = 0;
sem_t g_sem_full;
sem_t g_sem_empty;
pthread_mutex_t g_mutex;
pthread_t g_thread[CONSUMERS_COUNT+PRODUCERS_COUNT];
void* produce(void* arg)
{
int i;
int num = *(int*)arg;
free(arg);
while(1){
//当生产的未消费的产品量超过BUFFSIZE时将挂起等待
sem_wait(&g_sem_full);
pthread_mutex_lock(&g_mutex);
printf("%d begin produce\n", num);
for(i = 0; i < BUFFSIZE; i++)
{
printf("%02d ", i);
if(g_buffer[i] == -1)
{
printf("%s", "null");
}
else
{
printf("%d", g_buffer[i]);
}
if(i == in)
{
printf("\t<--produce");
}
printf("\n");
}
g_buffer[in] = produce_id;
in = (in + 1) % BUFFSIZE;
printf("%d end produce product %d\n\n", num, produce_id++);
pthread_mutex_unlock(&g_mutex);
sem_post(&g_sem_empty);//完成一次生产,新产品量加1
sleep(5);
}
return NULL;
}
void * consume(void* arg)
{
int i;
int num = *(int*)arg;
free(arg);
while(1){
//信号量的值为0时,表示没有产品生产出来,将挂起等待
sem_wait(&g_sem_empty);
pthread_mutex_lock(&g_mutex);
printf("%d begin consume\n", num);
for(i = 0; i < BUFFSIZE; i++)
{
printf("%02d ", i);
if(g_buffer[i] == -1)
{
printf("%s", "null");
}
else
{
printf("%d", g_buffer[i]);
}
if(i == out)
{
printf("\t<--consume");
}
printf("\n");
}
consume_id = g_buffer[out];
g_buffer[out] = -1;
out = (out+1) % BUFFSIZE;
printf("%d end consume product %d\n\n", num, consume_id);
pthread_mutex_unlock(&g_mutex);
sem_post(&g_sem_full);//表示已经消费一个产品
sleep(1);
}
return NULL;
}
int main()
{
int i;
for(i = 0; i < BUFFSIZE; i++)
{
g_buffer[i] = -1;
}
sem_init(&g_sem_full, 0, BUFFSIZE);
sem_init(&g_sem_empty, 0, 0);
pthread_mutex_init(&g_mutex, NULL);
for(i = 0; i < CONSUMERS_COUNT; i++)
{
int *p = (int*)malloc(sizeof(int));
*p = i;
pthread_create(&g_thread[i], NULL, consume, (void*)p);
}
for(i = 0; i < PRODUCERS_COUNT; i++)
{
int *p = (int*)malloc(sizeof(int));
*p = i;
pthread_create(&g_thread[CONSUMERS_COUNT+i], NULL, produce, (void*)p);
}
for(i = 0; i < CONSUMERS_COUNT+PRODUCERS_COUNT; i++)
{
pthread_join(g_thread[i], NULL);
}
pthread_mutex_destroy(&g_mutex);
sem_destroy(&g_sem_full);
sem_destroy(&g_sem_empty);
return 0;
}
释:
1)out = (out+1) % BUFFSIZE表示out的值在0-BUFFSIZE之间。
2)g_sem_full:实时记录可用的最大的存量。
3)g_sem_empty:记录未消费的产品个数。