POSIX信号量相关函数
有名信号量:
sem_open 信号量的打开
sem_close 信号量的关闭
sem_unlink 信号量的删除
无名信号量
sem_init 信号量初始化 (可以用于不同进程间的通信,取决于第二个参数非零,同时信号量的对象要在共享内存中)
sem_destroy 信号量销毁
sem_wait 对信号量的PV操作:可以对有名和无名操作
sem_post
POSIX互斥锁相关操作:
pthread_mutex_init 初始化一个互斥锁
pthread_mutex_lock 锁定操作
pthread_mutex_unlock 解锁操作
pthread_mutex_destroy 销毁锁(无名锁,也可以用于不同进程间操作)操作
自旋锁:
自旋锁类似于互斥锁,他的性能比互斥锁更高
自旋锁与互斥锁很重要的一个区别在与:线程在申请自旋锁的时候,线程不会挂起,他处于忙等待的状态
pthread_spin_init
pthread_spin_destroy
pthread_spin_lock
pthread_spin_unlock
读写锁:
1. 只要没有线程持有给定的读写锁用于写,那么任意数目的线程就可以持有读写锁用于读
2.仅当没有线程持有某个给定的读写锁用于读或者写时,才能分配读写锁用于写
3.读写锁用于读称为共享锁,读写锁用于写称为排他锁
pthread_rwlock_init
pthread_rwlock_destroy
int pthread_rwlock_rdlock
int pthread_rwlock_wrlock
int pthread_rwlock_unlock
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
}while(0)
#define CONSUMERS_COUNT 1
#define PRODUCERS_COUNT 2
#define BUFFSIZE 10
int g_buffer[BUFFSIZE];
pthread_t g_thread[CONSUMERS_COUNT + PRODUCERS_COUNT];
sem_t g_sem_full;
sem_t g_sem_empty;
pthread_mutex_t g_mutex;
unsigned short in = 0;
unsigned short out = 0;
unsigned produce_id = 0;
unsigned consum_id = 0;
void* consume(void* arg)
{
int i;
int num = (int)arg;
sem_wait(&g_sem_empty);
while(1)
{
pthread_mutex_lock(&g_mutex);
for(i = 0;i<BUFFSIZE ;i++)
{
printf("%02d",i);
sleep(1);
if(g_buffer[i] == -1)
{
printf("%s","NULL");
}
else
{
printf("g_buffer[%d]=%d",i,g_buffer[i]);
}
if(i == out)
{
printf("%\t<---consume");
}
printf("\n");
}
consum_id = g_buffer[out];
printf("begin consume product %d\n",consum_id );
g_buffer[out] = -1;
out = (out+1)%BUFFSIZE;
printf("end consume product %d\n",consum_id );
pthread_mutex_unlock(&g_mutex);
sem_post(&g_sem_full);
}
return NULL;
}
void* produce(void* arg)
{
int num = (int)arg;
int i;
while(1)
{
printf("%d wait buffer full\n",num);
sem_wait(&g_sem_full);
pthread_mutex_lock(&g_mutex);
for(i = 0;i < BUFFSIZE;i++)
{
printf("%02d",i);
sleep(1);
if(g_buffer[i] == -1)
{
printf("%s","NULL");
}
else
{
printf("g_buffer[%d]=%d",i,g_buffer[i]);
}
if(i == in)
{
printf("%\t<---produce");
}
printf("\n");
}
printf("begin produce product %d\n",produce_id);
g_buffer[in] = 9;
in = (in+1)%BUFFSIZE;
printf("end produce product %d\n",produce_id);
pthread_mutex_unlock(&g_mutex);
sem_post(&g_sem_empty);
//sleep(5);
}
return NULL;
}
int main()
{
sem_init(&g_sem_full, 0, BUFFSIZE);
sem_init(&g_sem_empty,0,0);
int i;
memset(g_buffer,0,sizeof(g_buffer));
for(i = 0;i< CONSUMERS_COUNT;i++)
{
pthread_create(&(g_thread[i]), NULL, consume, (void*)i);
}
for(i = CONSUMERS_COUNT;i<CONSUMERS_COUNT + PRODUCERS_COUNT;i++)
{
pthread_create(&(g_thread[i]), NULL, produce, (void*)i);
}
for(i = 0;i < CONSUMERS_COUNT + PRODUCERS_COUNT;i++)
{
pthread_join(g_thread[i],NULL);
}
sem_destroy(&g_sem_full);
sem_destroy(&g_sem_empty);
pthread_mutex_destroy(&g_mutex);
return 1;
}