POSIX信号量与互斥锁
2016-03-06 12:19
363 查看
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;
}
有名信号量:
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;
}
相关文章推荐
- LVS-NAT 模式配置
- Python---装饰器
- AOP
- 软件测试 作业一 (印象深刻的一些错误)
- 以用户名注册为例分析三种Action获取数据的方式
- Git同时提交到多个远程仓库
- JS、javascript获取当前时间戳的方法
- 文件
- RHEL 7.0 yum源
- POJ 1556 The Doors(计算几何+最短路)
- java设计模式学习笔记第三章
- 关于软件工程
- java dom4j 曾删改查、编码XML文件
- C++ UML Tips
- 白话Spring(基础篇)---编程式事务(1)
- poj1102数字打印,七段数字码
- irtualbox工具栏消失问题
- java设计模式学习笔记第二章
- 阅读计划
- js中substring和substr的用法