多线程条件变量(pthread_cond_wait)用法

条件变量是利用线程间共享得全局变量进行同步的一种机制,主要包括两个动作:一个线程等待“条件变量的条件成立”而挂起;另一个线程使“条件成立”给出条件成立信号。为了防止竞争,条件变量得使用总是和一个互斥锁结合在一起。

1、创建和注销

条件变量和互斥锁一样,有两种创建方式,静态方式使用PTHREAD_COND_INITIALIZER,动态方式使用pthread_coud_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr)函数,cond_attr设置为NULL即可。注销需要使用int pthread_cond_destroy(pthread_cond_t *cond);

2、等待和激发

int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime)

timewait方式表示超过时间条件没有满足则返回ETIMEOUT,结束等待 ,这个time是以绝对时间形式出现,即0表示格林尼治时间1970年1月1日0时0分0秒。为了防止多个线程同时请求pthread_cond_wait(),需要用互斥锁(mutex)来限定phread_cond_wait()的操作。对cond的操作必须是互斥的。下面是配合pthread_cleanup_push(),pthread_cleanup_pop()的一个示例程序:

#include "pthread.h"
#include "unistd.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"

struct _Node
{
	int number;
	struct _Node *next;
};
typedef struct _Node Node;

Node *head;

/*信号量和条件变量*/
static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

/*线程异常时处理函数*/
static void cleanup_handler(void *arg)
{
	printf("cleanup_handler\n");
	free(arg);
	(void)pthread_mutex_unlock(&mtx);
}

/*
pthread_cleanup_push注册一个回调函数,如果你的线程在对应的pthread_cleanup_pop之前异常退出(return是正常退出,其他是异常),那么系统就会执行这个回调函数(回调函数要做什么你自己决定)。但是如果在pthread_cleanup_pop之前没有异常退出,pthread_cleanup_pop就把对应的回调函数取消了
*/
static void* thread_func(void *arg)
{
	Node *p = NULL;
	printf("in thread_func()\n");
	
	/*注册线程异常处理函数*/
	pthread_cleanup_push(cleanup_handler, p);
	while (1)
	{
		pthread_mutex_lock(&mtx);
		while (NULL != head)
		{
			/*如果条件不满足,则挂起*/
			pthread_cond_wait(&cond, &mtx);
			p = head;
			printf("Got %d from front of queue\n",p->number);
			free(p);
			pthread_mutex_unlock(&mtx);
		}
	}

	/*清空线程异常处理函数*/
	pthread_cleanup_pop(0);
	return 0;
}

int main()
{
	pthread_t tid;
	int i;
	Node *p;

	pthread_create(&tid, NULL, thread_func, NULL);
	for(i = 0; i < 10; i++)
	{
		printf("int main():%d", i);
		p = (Node*)malloc(sizeof(Node));
		p->number = i;
		pthread_mutex_lock(&mtx);
		p->next = head;
		head = p;
		/*通知条件OK了*/
		pthread_cond_signal(&cond);
		pthread_mutex_unlock(&mtx);
		sleep(1);
	}

	printf("thread 1 wanna end then cancel thread2.\n");
	pthread_cancel(tid);
	pthread_join(tid, NULL);

	printf("All done\n");
	return 0;
}

 输出结果如下:

int main():0in thread_func()
int main():1Got 1 from front of queue
int main():2Got 2 from front of queue
int main():3Got 3 from front of queue
int main():4Got 4 from front of queue
int main():5Got 5 from front of queue
int main():6Got 6 from front of queue
int main():7Got 7 from front of queue
int main():8Got 8 from front of queue
int main():9Got 9 from front of queue
thread 1 wanna end then cancel thread2.
cleanup_handler
All done

 

转载于:https://www.cnblogs.com/binmaizhai/archive/2013/03/21/2973554.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值