linux多執行緒程式設計,替代sleep的幾種方式
我只想要程序的某個執行緒休眠一段時間的,可是用sleep()是將整個程序都休眠的,這個可能就達不到,我們想要的效果了。 目前我知道有三種方式:
1 usleep
這個是輕量級的, 聽說能可一實現執行緒休眠, 我個人並不喜歡這種方式,所以我沒有驗證它的可行信(個人不推薦)。
2 select
這個可以,我也用過這種方式, 它是在輪詢。
3 pthread_cond_timedwait
採用pthread_cond_timedwait(pthread_cond_t* cond, pthread_mutex_t *mutex, const struct timespec *abstime)可以優雅的解決該問題,設定等待條件變數cond,如果超時,則返回;如果等待到條件變數cond,也返回。本文暫不將內部機理,僅演示一個demo。
首先,看這段程式碼,thr_fn為一個執行緒函式:
輸入q後,需要等執行緒從sleep中醒來(由掛起狀態變為執行狀態),即最壞情況要等10s,執行緒才會被join。採用sleep的缺點:不能及時喚醒執行緒。#include <stdio.h> #include <stdlib.h> int flag = 1; void * thr_fn(void * arg) { while (flag){ printf("******\n"); sleep(10); } printf("sleep test thread exit\n"); } int main() { pthread_t thread; if (0 != pthread_create(&thread, NULL, thr_fn, NULL)) { printf("error when create pthread,%d\n", errno); return 1; } char c ; while ((c = getchar()) != 'q'); printf("Now terminate the thread!\n"); flag = 0; printf("Wait for thread to exit\n"); pthread_join(thread, NULL); printf("Bye\n"); return 0; }
採用pthread_cond_timedwait函式實現的如下:
#include <stdio.h> #include <sys/time.h> #include <unistd.h> #include <pthread.h> #include <errno.h> static pthread_t thread; static pthread_cond_t cond; static pthread_mutex_t mutex; static int flag = 1; void * thr_fn(void * arg) { struct timeval now; struct timespec outtime; pthread_mutex_lock(&mutex); while (flag) { printf("*****\n"); gettimeofday(&now, NULL); outtime.tv_sec = now.tv_sec + 5; outtime.tv_nsec = now.tv_usec * 1000; pthread_cond_timedwait(&cond, &mutex, &outtime); } pthread_mutex_unlock(&mutex); printf("cond thread exit\n"); } int main(void) { pthread_mutex_init(&mutex, NULL); pthread_cond_init(&cond, NULL); if (0 != pthread_create(&thread, NULL, thr_fn, NULL)) { printf("error when create pthread,%d\n", errno); return 1; } char c ; while ((c = getchar()) != 'q'); printf("Now terminate the thread!\n"); pthread_mutex_lock(&mutex); flag = 0; pthread_cond_signal(&cond); pthread_mutex_unlock(&mutex); printf("Wait for thread to exit\n"); pthread_join(thread, NULL); printf("Bye\n"); return 0; }
pthread_cond_timedwait()函式阻塞住呼叫該函式的執行緒,等待由cond指定的條件被觸發(pthread_cond_broadcast() or pthread_cond_signal())。
當pthread_cond_timedwait()被呼叫時,呼叫執行緒必須已經鎖住了mutex。函式pthread_cond_timedwait()會對mutex進行【解鎖和執行對條件的等待】(原子操作)。這裡的原子意味著:解鎖和執行條件的等待是原則的,一體的。(In this case, atomically means with respect to the mutex andthe condition variable and other access by threads to those objectsthrough the pthread condition variable interfaces.)
如果等待條件滿足或超時,或執行緒被取消,呼叫執行緒需要線上程繼續執行前先自動鎖住mutex,如果沒有鎖住mutex,產生EPERM錯誤。即,該函式返回時,mutex已經被呼叫執行緒鎖住。
等待的時間通過abstime引數(絕對系統時間,過了該時刻就超時)指定,超時則返回ETIMEDOUT錯誤碼。開始等待後,等待時間不受系統時鐘改變的影響。
儘管時間通過秒和納秒指定,系統時間是毫秒粒度的。需要根據排程和優先順序原因,設定的時間長度應該比預想的時間要多或者少點。可以通過使用系統時鐘介面gettimeofday()獲得timeval結構體。