一、概述
本节将继续说明有关线程编程常用 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。
acl 库下载:https://sourceforge.net/projects/acl/
github: https://github.com/acl-dev/acl
相关推荐
2 基本线程编程.............................................................................................................................................23 线程库.......................................
2 基本线程编程23 线程库................................................................................................................................................. 23 创建缺省线程...................
用线程编程是技巧性很强的且不可移植。 而在Java中却完全不同。Java的线程工具易于使用,并且像Java中的其他东西一样可以在不同的平台之间移植。这是一件好事,因为如果没有线程,那么除了最简单的applet之外,几乎...
常见的多线程API和用法 pthread_self函数 pthread_create函数 pthread_exit函数 pthread_join函数 pthread_detach函数 pthread_equal函数
第五章 Java线程编程的例子 数据结构和容器 简单的同步例子 一个网络服务器类 AsyncInputStream类 使用TCPServer和AsynclnputStream 总结 第六章 Java线程调度 线程调度概述 何时调度是重要的 调度和线程优先级 ...
数据库应用程序编程接口(DB-API) 17.1. 知识点 17.2. 良好的编程习惯 17.3. 常见编程错误 17.4. 移植性提示 18. 进程管理 18.1. 知识点 18.2. 良好的编程习惯 18.3. 移植性提示 19. 多线程处理 19.1. ...
│ 高并发编程第一阶段26讲、多线程下的生产者消费者模型,以及详细介绍notifyAll方法.mp4 │ 高并发编程第一阶段27讲、wait和sleep的本质区别是什么,深入分析(面试常见问题).mp4 │ 高并发编程第一阶段28讲、...
资源内包含java常见的技术帮助文档。java编程规范、线程使用、集合框架等等。很适合初学者以及拓展资料
│ 高并发编程第一阶段26讲、多线程下的生产者消费者模型,以及详细介绍notifyAll方法.mp4 │ 高并发编程第一阶段27讲、wait和sleep的本质区别是什么,深入分析(面试常见问题).mp4 │ 高并发编程第一阶段28讲、...
ch05 多线程编程 ch06 I/O及网络编程 ch07 数据库RMS编程 ch08 浮点数编程 ch09 多媒体及GAME API编程 ch10 安全、加密及代码优化 ch11 扩展类库及供应商提供的API ch12 与服务端联合搭建移动应用 ch13 XML ...
4. 并发与多线程编程 技巧10:线程同步与并发控制 技巧11:避免死锁的策略与设计模式 技巧12:线程安全编程与锁机制的正确使用 5. .NET框架高级特性 技巧13:LINQ查询表达式的高效运用 技巧14:Lambda表达式与委托...
此外,书中还深入剖析了并发编程中的常见问题,如死锁、活锁、饥饿等,并提供了相应的解决方案和最佳实践。 本书注重理论与实践相结合,通过大量的示例代码和案例分析,帮助读者更好地理解和掌握并发编程的技巧和...
面向对象的编程思想、Java语言的基础知识、异常处理、类与对象的生命周期、多线程、Java集合、泛型、Annotation标注、输入/输出和GUI编程,以及JDK8引入的如虎添翼的新特征,比如支持函数式编程的Lambda表达式和功能...
Java API:常见对象 更新中 Java API:常见对象-阶段性测试 更新中 Java API:集合框架 更新中 IO/输入输出 更新中 IO/输入输出-阶段性测试 更新中 多线程 更新中 图形用户界面编程GUI 更新中 网络编程 更新中 反射-...
- 多线程编程 2. 数据库: - 熟悉SQL语言 - 了解关系型数据库和非关系型数据库 - 数据库连接池 - 数据库事务 3. Spring框架: - Spring Boot - Spring MVC - Spring Data - Spring Security - Spring...
在讲解多线程、常用API、集合、IO、GUI、网络编程的章节中,通过剖析案例、分析代码含义、解决常见问题等方式进行阐述,并且在本书中还添加了许多 资源太大,传百度网盘了,链接在附件中,有需要的同学自取。
常见的对象方法: 简化了Object常用方法的实现, 如 hashCode() 和 toString()。 4. 排序: Guava 强大的 "fluent Comparator"比较器, 提供多关键字排序。 5. Throwable类: 简化了异常检查和错误传播。 二...
多线程编程:线程的创建、同步机制、并发工具。 网络编程:Socket编程、URL和URLConnection。 数据库连接:JDBC的使用和数据库交互。 Java Web技术:Servlet、JSP、MVC架构。 框架应用:Spring、Hibernate、Struts等...
1. 多线程和并发编程:学习使用Java并发包(如java.util.concurrent)处理多线程编程,了解线程池、锁机制和并发集合等。 2. 性能优化:学习分析和调优Java应用程序的性能,了解内存管理、垃圾回收、性能监测和调优...