一、概述
本节将继续说明有关线程编程常用 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
相关推荐
本篇将深入探讨多线程编程模型,包括相关概念、操作系统提供的API以及在实际编程中遇到的问题和解决方案。 首先,我们要理解多线程中涉及的各种对象的概念。线程是执行路径或程序执行的顺序流,它是进程中的一个...
《Windows多线程编程技术与实例(C++)》是一本深入探讨Windows环境下多线程编程的书籍,特别适合正在学习或已经从事C++多线程开发的人员阅读。本书通过丰富的实例,详细讲解了如何在Windows操作系统中利用C++进行...
这份“JAVA多线程编程技术PDF”是学习和掌握这一领域的经典资料,涵盖了多线程的全部知识点。 首先,多线程的核心概念包括线程的创建与启动。在Java中,可以通过实现Runnable接口或继承Thread类来创建线程。创建后...
总体来说,Linux多线程编程手册是一个关于在Linux环境下使用多线程API进行编程的全面指南。对于希望构建高性能、高响应速度应用程序的开发者来说,这是一份宝贵的资源。手册中不仅详细介绍了多线程编程的理论知识,...
### 多线程编程指南:全面解析与应用 #### 多线程编程的定义与重要性 多线程编程是一种让程序...合理使用线程属性和同步对象,遵循良好的编程实践,可以避免常见的多线程编程陷阱,构建稳定、高效的多线程应用程序。
多线程编程是一种让多个代码路径在同一个程序中同时运行的技术,它允许多个执行流(线程)并发执行。在iOS开发中,多线程编程可以帮助开发者充分利用多核处理器的性能,提高应用程序的响应性和运行效率。然而,多...
本文将详细介绍Linux下的多线程编程原理、基本API使用以及示例分析。 #### 二、POSIX线程(pthread) ##### 2.1 POSIX线程简介 Linux下的多线程编程基于POSIX线程标准,即pthread。该标准定义了一系列API,用于...
在IT领域,多线程编程是一项基础且重要的技术,尤其在Windows操作系统环境下。"实验一:WindowsThreads多线程编程实验"旨在让学生深入理解和实践如何在Windows系统中创建和管理线程。通过这个实验,我们可以学习到...
MFC通过提供CWinThread类来支持多线程编程,它封装了Windows API的线程创建和管理功能。 创建MFC多线程主要涉及以下几个步骤: 1. **继承CWinThread**:首先,你需要创建一个新的C++类,并让它继承自CWinThread。...
#### 四、多线程编程常见问题及解决策略 在实际开发过程中,可能会遇到以下几种常见问题: 1. **竞态条件**:当两个或多个线程同时访问相同的共享资源时,可能会导致数据不一致的问题。解决方法通常是使用互斥锁或...
在计算机科学领域,多线程编程是一种常见的技术手段,用于提高程序的执行效率和响应能力。通过本篇文章,我们将探讨多线程编程的基本概念及其在实际开发中的应用。 #### 二、问题背景与解决方案 假设我们正在开发一...
压缩包中的"threadtech_jb51.rar"可能包含具体的多线程编程示例,如并发下载、并行计算、用户界面更新等常见应用场景。这些实例可以帮助理解如何在实际项目中有效地使用多线程。 总结,掌握VC++多线程编程不仅需要...
在Linux操作系统中,多线程编程是一种常见且重要的编程模型,它允许多个执行流(线程)在一个进程中同时运行,以提高程序的并发性和资源利用率。多线程在系统开发中扮演着关键角色,特别是在需要高性能计算、实时...
《深入浅出Win32多线程编程》是一本专为Windows平台开发者设计的书籍,旨在帮助读者理解和掌握在Win32环境下进行多线程编程的技术与实践。多线程编程是现代软件开发中的重要组成部分,尤其是在处理高性能计算、并发...
死锁是多线程编程中常见的问题,当两个或更多线程相互等待对方释放资源时就会发生死锁。避免死锁的方法包括避免循环等待、设置超时、资源预分配等。此外,活锁也是需要注意的问题,即线程不断重试导致永远无法进行...
死锁是多线程编程中的一种常见问题,发生在两个或更多线程相互等待对方释放资源,从而导致所有线程都无法继续的情况。避免死锁的方法包括避免循环等待、设置超时、使用死锁检测算法等。 线程优先级也是Java多线程中...
此外,死锁和饥饿是多线程编程中的两个常见问题,需要特别注意。死锁发生在两个或更多线程相互等待对方释放资源时,而饥饿则是一个线程因其他高优先级线程持续占用资源而无法获得执行。解决这些问题通常需要精心设计...
在Linux系统中,多线程编程是一种常见的编程模式,它允许多个执行流在同一程序内同时运行,从而提高系统的资源利用率和并发性能。本资料主要针对Linux环境下的多线程编程进行深入探讨。 首先,我们需要了解Linux下...