文档章节

线程编程常见API简介(下)

郑树新
 郑树新
发布于 2014/09/03 12:11
字数 1197
阅读 14
收藏 1

 

一、概述

      本节将继续说明有关线程编程常用 API 的使用方法,主要说一下与线程条件变量及线程信号通知的 API。通过这些 API 可以实现线程之间的同步及通信机制。

 

二、线程条件变量 API

 1)初始化/销毁线程条件变量:pthread_cond_init/pthread_cond_destroy;在 acl 库中相应的 API 为 acl_pthread_cond_init/acl_pthread_cond_destroy。

/**
 * 用线程条件变量属性初始化线程条件变量对象
 * @param cond {pthread_cond_t*} 线程条件变量对象
 * @param attr {const pthread_condattr_t*} 条件变量属性,用来设置线程
 *    条件变量的属性,该参数可以由 pthread_condattr_init/pthread_condattr_destroy 初始化和销毁;该参数可以设为 NULL
 * @return {int} 返回 0 表示成功,否则出错,错误号可以用 strerror 打印
 */
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);

/**
 * 销毁线程条件变量对象通过 pthread_cond_init 分配的资源
 * @param cond {pthread_cond_t*} 线程条件变量对象
 * @return {int} 返回 0 表示成功,否则出错
 */
int pthread_cond_destroy(pthread_cond_t *cond);

 

 2)等待线程条件变量被其它线程通知:pthread_cond_wait/pthread_cond_timedwait,在 acl 库中对应的 API 为 acl_pthread_cond_wait/acl_pthread_cond_timedwait。

/**
 * 线程阻塞在线程条件变量直至该线程条件变量被通知,在等待状态,该线程不会
 * 拥有线程锁;当线程条件变量被通知时,该线程首先会对线程锁加锁,然后返回
 * 给调用者,即当该 API 返回时,当前线程已经拥有了其中的线程锁
 * @param cond {pthread_cond_t*} 线程条件变量对象
 * @param mutex {pthread_mutex_t*} 与线程条件变量配合使用的线程锁
 * @return {int} 返回 0 表示阻塞当前线程的线程条件变量被其它线程通知,同
 *   时当前线程获得相应的线程锁;否则,表示出错,出错原因一般是输入的参数非法
 */
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t  *mutex);

/**
 * 当前线程阻塞在线程条件变量上,直到该条件变量被其它线程通知或设定的等待
 * 超时时间到达,该 API 相比 pthread_cond_wait 多出一个等待超时时间
 * @param cond {pthread_cond_t*} 线程条件变量对象
 * @param mutex {pthread_mutex_t*} 与线程条件变量配合使用的线程锁
 * @param abstime {const struct timespec*} 超时时间截,当时间超过该
 *    时间截后,即使线程条件变量未被通知,该 API 也会返回
 * @return {int} 返回 0 表示阻塞当前线程的线程条件变量被其它线程通知,同
 *   时当前线程获得相应的线程锁;否则,如果返回值为 ETIMEDOUT(在 acl 库
 *   中表示为 ACL_ETIMEDOUT)则表示该 API 是因为超时才返回的,同时会将
 *   线程锁加锁,当为其它返回值时一般是因为输入参数非法导致
 */
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime);

        上面两个等待线程条件变量的 API中,pthread_cond_timedwait 对于设计半驻留式线程非常有用,象 acl 库中的半驻留式线程池就用到了它。

 

 3)通知阻塞在线程条件变量上的线程:pthread_cond_signal/pthread_cond_broadcast,在 acl 库中相应表现形式为:acl_pthread_cond_signal/acl_pthread_cond_broadcast。

/**
 * 唤醒阻塞在某个线程条件变量上的一个线程
 * @param cond {pthread_cond_t*} 线程条件变量对象
 * @return {int} 返回 0 表示成功,否则表示出错
 */
int pthread_cond_signal(pthread_cond_t *cond);

/**
 * 唤醒阻塞在某个线程条件变量上的所有线程,当所有阻塞在线程条件变量上的
 * 所有线程被唤醒后,会首先抢占参数中输入的线程锁(有可能是同一个线程锁,
 * 也有可能不是),在获得那个线程锁后那些被唤醒的线程才会返回
 * @param cond {pthread_cond_t*} 线程条件变量对象
 * @return {int} 返回 0 表示成功通知所有阻塞在线程条件变量上的线程,否则
 *    表示出错
 */
int pthread_cond_broadcast(pthread_cond_t *cond);

 

三、示例

#include <stdio.h>
#include <assert.h>
#include <pthread.h>

/* 快速初始化线程锁和线程条件变量 */
static pthread_mutex_t __mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t __cond = PTHREAD_COND_INITIALIZER;

static void *thread_waiting(void* arg)
{
	(void) arg;
	printf("thread: %ld waiting ...\r\n", pthread_self());

	/* 阻塞在线程条件变量上, */
	assert(pthread_cond_wait(__cond, __mutex) == 0);

	/* 该线程被唤醒,同时拥有了线程锁 __mutex */
	printf("thread: %ld wakeup by other thread\r\n", pthread_self());
	return NULL;
}

int main(void)
{
	pthread_t tid;

	/* 创建阻塞在线程条件变量上的子线程 */
	assert(pthread_create(&tid, NULL, thread_waiting, NULL) == 0);
	sleep(10);  /* 主线程休息 10 秒 */

	/* 唤醒阻塞在线程条件变量上的子线程 */
	assert(pthread_cond_signal(__cond) == 0);

	/* 接管子线程的退出状态 */
	assert(pthread_join(&tid) == 0);

	return 0;
}

       该例子非常简单,用户可以在自己的程序中灵活使用这些 API。

 

个人微博:http://weibo.com/zsxxsz

线程编程常见API简介(上)

线程编程常见API简介(中)

acl 库下载:https://sourceforge.net/projects/acl/

© 著作权归作者所有

郑树新

郑树新

粉丝 105
博文 87
码字总数 161171
作品 2
昌平
程序员
私信 提问
Linux多线程并发服务器编程(线程池,FTP服务器)

分享网盘下载:https://pan.baidu.com/s/1gfNCcXt 密码: irfk 内容简介 本课程从最基础的进程、线程概念讲起逐步深入,通过理论与实践结合的方式,使学员快说掌握linux多线程网络编程技术,并...

人气王子333
2018/06/26
0
0
一年走向【Java架构师】之葵花宝典

大多数时候,不是我们不努力,而是不知从何下手,我深知一份好的学习资料是多么的重要,我们通常会把大量的时间都浪费在找资源上,本人搜集学习java架构师的经典学习路线如下可供参考!!! 一...

我一路狂奔
2017/05/20
632
1
这绝对是有史以来最详细的web前端学习攻略

  第一阶段:   HTML+CSS:   HTML进阶、CSS进阶、div+css布局、HTML+css整站开发、   JavaScript基础:   Js基础教程、js内置对象常用方法、常见DOM树操作大全、ECMAscript、DOM、...

学习web前端
2017/10/12
0
0
知识点

蓝厂: 1.事件分发流程 2.View的渲染机制 3.动画的原理,底层如何给上层信号 编译打包的过程 5.Android有多个资源文件夹,应用在不同分辨率下是如何查找对应文件夹下的资源的,描述整个过程 ...

咖喱配胡椒
2017/10/10
0
0
six ckhddydbxclq

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 https://blog.csdn.net/zhoutianzi12/article/details/95601351 文章目录 6.3 SISD、MIMD、S...

fgh431
08/25
0
0

没有更多内容

加载失败,请刷新页面

加载更多

新架构、新角色:TiDB Community Upgrade!

作者:Jian Zhang 经过几年的发展,TiDB 社区已经逐渐成熟,但是随着社区的发展壮大,我们逐渐感受到了现在社区架构上的一些不足。经过一系列的思考和总结,我们决定升级和调整目前社区组织架...

TiDB
28分钟前
5
0
jquery qrcode库提示not function

jquery qrcode 这个库能用,但是必须在初始化的时候,官方给的使用方法是 引入qrcode的库文件后,在js中写以下 html <div id="qrcode"></div> js jQuery('#qrcode').qrcode({ render: ......

shikamaru
32分钟前
13
0
MySQL数据库去重的简单方案

利用 distinct 对需要处理的字段进行去重 select distinct 字段名 from 表名 利用group by select * from 表名 group by 字段名 利用having select * from 表名 group by 字段名 having 字段...

FeanLau
35分钟前
9
0
字符串转换成整数

实现一个 atoi 函数,使其能将字符串转换成整数。 首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。 当我们寻找到的第一个非空字符为正或者负号时,则将该...

蔚蓝_晴天
46分钟前
8
0
Eureka客户端续约及服务端过期租约清理源码解析

在之前的文章:EurekaClient自动装配及启动流程解析中,我们提到了在构造DiscoveryClient时除了包含注册流程之外,还调度了一个心跳线程: scheduler.schedule( new Ti...

Java学习录
57分钟前
10
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部