線程順序迴圈執行的場景在多線程編程中並不罕見,尤其是在需要協調多個線程按特定順序重覆執行任務的情況下。以下是幾個常見的例子: 生產者-消費者模型:在這種模型中,生產者線程生成數據並將其放入緩衝區,而消費者線程從緩衝區取出數據進行處理。這種情況下,生產者和消費者線程通常按順序交替運行。 流水線處理:在 ...
線程順序迴圈執行的場景在多線程編程中並不罕見,尤其是在需要協調多個線程按特定順序重覆執行任務的情況下。以下是幾個常見的例子:
- 生產者-消費者模型:在這種模型中,生產者線程生成數據並將其放入緩衝區,而消費者線程從緩衝區取出數據進行處理。這種情況下,生產者和消費者線程通常按順序交替運行。
- 流水線處理:在某些應用中,數據處理分為多個步驟,每個步驟由不同的線程負責。例如,在圖像處理流水線中,可能有一個線程讀取圖像數據,一個線程處理圖像,一個線程保存處理後的圖像。每個線程按順序操作,形成一個迴圈處理流水線。
- 周期性任務調度:某些系統需要周期性地執行一組任務,例如感測器數據採集系統,每個感測器的數據採集線程需要按順序運行,並且在一定時間後重新開始。
為了更好地理解,我們可以通過一個具體的例子來說明如何使用信號量和多線程實現順序迴圈執行。
利用POSIX無名信號量實現三個線程 T1、T2 和 T3,按順序迴圈執行各自的任務。
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#define NUM_ITERATIONS 3
sem_t sem1, sem2, sem3;
void* thread1(void* arg) {
for (int i = 0; i < NUM_ITERATIONS; ++i) {
sem_wait(&sem1); // 等待信號量
printf("Thread 1 is running\n");
sleep(1); // 模擬工作
printf("Thread 1 has finished\n");
sem_post(&sem2); // 通知thread2可以開始
}
return NULL;
}
void* thread2(void* arg) {
for (int i = 0; i < NUM_ITERATIONS; ++i) {
sem_wait(&sem2); // 等待信號量
printf("Thread 2 is running\n");
sleep(1); // 模擬工作
printf("Thread 2 has finished\n");
sem_post(&sem3); // 通知thread3可以開始
}
return NULL;
}
void* thread3(void* arg) {
for (int i = 0; i < NUM_ITERATIONS; ++i) {
sem_wait(&sem3); // 等待信號量
printf("Thread 3 is running\n");
sleep(1); // 模擬工作
printf("Thread 3 has finished\n");
sem_post(&sem1); // 通知thread1可以開始
}
return NULL;
}
int main() {
pthread_t t1, t2, t3;
// 初始化信號量
sem_init(&sem1, 0, 1); // 初始信號量為1,使線程1首先運行
sem_init(&sem2, 0, 0);
sem_init(&sem3, 0, 0);
/*
int sem_init(sem_t *sem, int pshared, unsigned int value);
pshared信號量的作用範圍,0為線程間,非0為進程間
value 信號量值,首先執行的線程信號量設置為1,其他的為0
*/
// 創建線程
pthread_create(&t1, NULL, thread1, NULL);
pthread_create(&t2, NULL, thread2, NULL);
pthread_create(&t3, NULL, thread3, NULL);
// 等待所有線程完成
pthread_join(t1, NULL);
pthread_join(t2, NULL);
pthread_join(t3, NULL);
// 銷毀信號量
sem_destroy(&sem1);
sem_destroy(&sem2);
sem_destroy(&sem3);
printf("All threads have finished execution.\n");
return 0;
}
輸出結果:
Thread 1 is running
Thread 1 has finished
Thread 2 is running
Thread 2 has finished
Thread 3 is running
Thread 3 has finished
Thread 1 is running
Thread 1 has finished
Thread 2 is running
Thread 2 has finished
Thread 3 is running
Thread 3 has finished
Thread 1 is running
Thread 1 has finished
Thread 2 is running
...