返回
如何使用条件变量周期性触发并等待 pthread 工作线程完成?
Linux
2024-03-22 07:44:39
周期性触发和等待完成 pthread 工作线程
简介
在多线程编程中,经常需要协调多个线程的执行,以确保任务以特定顺序或周期性地执行。本文将探讨如何使用条件变量来周期性地触发一组 pthread 工作线程并等待它们全部完成。
使用条件变量
条件变量是一种线程同步机制,允许一个线程等待特定条件满足,然后继续执行。在我们的场景中,条件是所有工作线程都已完成其任务。
以下步骤演示了如何使用条件变量实现此功能:
1. 创建条件变量和互斥锁
首先,我们需要创建一个条件变量 cond
和一个互斥锁 mutex
。互斥锁用于保护对共享数据(条件变量)的访问。
pthread_cond_t cond;
pthread_mutex_t mutex;
pthread_cond_init(&cond, NULL);
pthread_mutex_init(&mutex, NULL);
2. 在工作线程中
每个工作线程在完成任务后应执行以下步骤:
- 获取互斥锁以保护条件变量。
- 信号条件变量,表示已完成任务。
- 释放互斥锁。
pthread_mutex_lock(&mutex);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
3. 在主线程中
主线程负责触发工作线程并等待它们完成。它将执行以下步骤:
- 触发工作线程。
- 获取互斥锁以保护条件变量。
- 等待条件变量,直到所有工作线程都完成任务。
- 释放互斥锁。
pthread_barrier_wait(&b); // 触发工作线程
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond, &mutex); // 等待工作线程完成
pthread_mutex_unlock(&mutex);
代码示例
以下是一个代码示例,展示了如何使用条件变量来周期性地触发和等待 pthread 工作线程:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define NTHREADS 4
pthread_cond_t cond;
pthread_mutex_t mutex;
int phase = 0;
int cycle = 0;
// 工作线程函数
void *thread_func(void *x) {
int tid = ((int *)x)[0];
while (1) {
printf("%d: %d %d\n", cycle, tid, phase);
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
}
return NULL;
}
int main() {
pthread_t threadids[NTHREADS]; // 存储操作系统线程 ID
int thread_args[NTHREADS]; // 线程参数
int rc, i;
// 初始化条件变量和互斥锁
pthread_cond_init(&cond, NULL);
pthread_mutex_init(&mutex, NULL);
// 创建线程
for (i = 0; i < NTHREADS; ++i) {
thread_args[i] = i;
if ((rc = pthread_create(&threadids[i], NULL, thread_func, (void *)&thread_args[i])) != 0) {
fprintf(stderr, "无法创建线程 %d\n", i);
exit(8);
}
}
for (i = 0; i < 10; i++) { // 执行十次迭代
printf("cycle %d\n", i);
phase = (phase + 1) % 3;
cycle++;
// 触发工作线程
pthread_cond_broadcast(&cond);
// 等待工作线程完成
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
}
exit(0);
}
结论
通过使用条件变量,我们可以轻松有效地周期性地触发一组 pthread 工作线程并等待它们全部完成。这种方法对于协调多线程任务并确保按预期执行至关重要。
常见问题解答
- 什么是条件变量?
答:条件变量是一种线程同步机制,允许一个线程等待特定条件满足,然后继续执行。
- 如何使用条件变量协调工作线程?
答:工作线程在完成任务后信号条件变量,而主线程等待条件变量,直到所有工作线程都完成任务。
- 为什么我们需要一个互斥锁?
答:互斥锁用于保护对共享数据(条件变量)的访问,防止竞争条件。
- 代码示例中的
phase
和cycle
变量的作用是什么?
答:phase
和 cycle
变量用于跟踪工作线程的当前阶段和执行的迭代次数。
- 这个技术有哪些实际应用?
答:这个技术可以应用于各种场景,如并行计算、数据处理和多线程 Web 服务器。