读书笔记之linux/unix系统编程手册(30)

线程同步
1.互斥量可以帮助线程同步,条件变量允许线程相互通知共享变量的状态发生变化
2.互斥量有已锁定和未锁定两种状态
3.如果互斥量已被锁定,那么mutex_lock()调用会一直阻塞,直至被解锁,那时才返回
4.如果调用lock()之前,线程已经锁定,线程会陷入死锁
5.每个线程成功的锁住一个互斥量,接着试图对已为另一个线程锁定的互斥量加锁,两个线程将死锁,两个线程分别锁定两个互斥量所导致的死锁
6.线程不应对不为自己所用的互斥量解锁
7.线程不应对一个尚未锁定的互斥量做解锁动作(linux两种操作都会成功,所以要自己小心解锁)
8.条件变量允许一个线程就某个共享变量(或其他共享资源)的状态变化通知其他线程,并让其他线程等待(阻塞)这一通知
9.条件变量会防止线程不停的循环检查变量的状态,故而造成cpu资源浪费,条件变量会允许一个线程休眠(等待),直至收到另一个线程去执行
10.pthread_cond_signal比pthread_cond_broadcast()更有效率。可避免发生以下状况:
(1)同时唤醒所有等待线程
(2)某一线程首先得到调度
(3)剩下的每个线程轮流锁定互斥量并检测共享资源的状态。不过由于第一的线程所做的工作,余下的线程发现无事可做,随即解锁互斥量转而休眠
11.相形之下broad_cast()唤醒所有线程,适合条件变量判定条件不同的情况
12.pthread_cond_wait()会自动执行最后两步中对互斥量的解锁和加锁的动作,换句话说,在函数的调用线程陷入对条件变量之前,其他线程不可能获取该互斥量,也不可能就该条件变量发出信号
13.当cond_wait()返回时,并不能确定判断条件的状态,所以应该重新判断条件,在条件不满足的情况下继续休眠等待
14.条件变量返回时,之所以不能对判断条件的状态做任何假设,其理由如下:
(1)其他线程可能会率先醒过来,改变判断条件的状态
(2)设计时设置"宽松的"判断条件或许更为简单
(3)可能会发生虚假唤醒的情况

15.pthread_cond_int()对条件变量进行动态初始化

16.在某些实现中,先解锁互斥量再通知条件变量可能比反序执行效率更高。如果仅在发出条件变量信号后才解锁互斥量,执行cond_wait调用的线程可能会在互斥量仍处于加锁状态下就醒来,当其发现互斥量仍未解锁,会立即再次休眠,这会导致两个多余的上下文切换。


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#define CELL 10
#define FLOOR 0
int i=0;
pthread_mutex_t mutex;
pthread_cond_t cond_pro,cond_con;
void* pro_handler(void* arg)
{
	pthread_detach(pthread_self());
	while(1)
	{
		pthread_mutex_lock(&mutex);
		while(i>=CELL)
		{
			pthread_cond_wait(&cond_pro,&mutex);
		}
		i++;
		if(i==1)
		{
			pthread_cond_signal(&cond_con);
		}
		printf("add i:%d\n",i);
		pthread_mutex_unlock(&mutex);
		sleep(rand()%5+1);
	}
}
void* con_handler(void* arg)
{
	pthread_mutex_lock(&mutex);
	while(i<=FLOOR)
	{
		pthread_cond_wait(&cond_con,&mutex);
	}
	i--;
	if(i==9)
	{
		pthread_cond_signal(&cond_pro);
	}
	printf("con i:%d\n",i);
	pthread_mutex_unlock(&mutex);
	sleep(rand()%5+1);
}
int main(int argc,char* argv[])
{
	int con_
	pthread_t thd_con,thd_pro;
	pthread_create(&thd_con,NULL,,NULL);
	pthread_create(&thd_pro,NULL,,NULL);
	return 0;
}
//
#include<stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#define cnt 20
typedef struct tag
{
	int arr[cnt+1];
	int front;
	int tail;
}que;
int is_que_empty(que* q)
{
	if((q->front%(cnt+1))==(q->tail%(cnt+1)))
		return 1;
	return 0;
}
int is_que_full(que* q)
{
	if((q->front%(cnt+1))==((q->tail+1)%(cnt+1)))
		return 1;
	return 0;
}
int que_cnt(que* q)
{
	return ((*q).tail-(*q).front+cnt+1)%(cnt+1);
}
pthread_mutex_t  mutex ;
pthread_cond_t cond_pro, cond_con ;
que* q;
void* pro_handler(void* arg)
{
	pthread_detach(pthread_self());
	while(1)
	{
		pthread_mutex_lock(&mutex);
		//printf("produce\n");
		while(is_que_full(q))
		{
			pthread_cond_wait(&cond_pro, &mutex);
		}
		//que_cnt(q)++;
		q->tail=(q->tail+1)%(cnt+1);
		printf("produce: %d\n",que_cnt(q));
		if(que_cnt(q)==1)
		{
			pthread_cond_broadcast(&cond_con);
		}
		pthread_mutex_unlock(&mutex);
		sleep(rand()%3+1);
	}
}
void* con_handler(void* arg)
{
	pthread_detach(pthread_self());
	while(1)
	{
		pthread_mutex_lock(&mutex);
		//printf("consumer\n");
		while(is_que_empty(q))
		{
			pthread_cond_wait(&cond_con, &mutex);
		}
		//que_cnt(q)--;
		q->front=(q->front+1)%(cnt+1);
		printf("consume: %d\n",que_cnt(q));
		if(que_cnt(q)==19)
		{
			pthread_cond_broadcast(&cond_pro);
		}
		pthread_mutex_unlock(&mutex);
		sleep(rand()%3+1);
	}
}
int main(int argc,char* argv[])
{
	int con_cnt , pro_cnt ;
	pro_cnt = atoi(argv[1]) ;
	con_cnt = atoi(argv[2]) ;
	q=(que*)calloc(1,sizeof(que));
	srand(getpid());
	pthread_mutex_init(&mutex, NULL);
	pthread_cond_init(&cond_pro, NULL);
	pthread_cond_init(&cond_con, NULL);
	pthread_t* arr = (pthread_t*)calloc(con_cnt + pro_cnt, sizeof(pthread_t));
	int index = 0 ;
	while(pro_cnt > 0)
	{
		pthread_create(arr + index , NULL, pro_handler, NULL);
		index ++ ;
		pro_cnt -- ;
	}
	sleep(5);
	while(con_cnt > 0)
	{
		pthread_create(arr + index , NULL, con_handler, NULL);
		index ++ ;
		con_cnt -- ;
	}
	while(1) ;
	pthread_mutex_destroy(&mutex);
	pthread_cond_destroy(&cond_pro);
	pthread_cond_destroy(&cond_con);
	return 0;
}
















  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值