146
技術社區[雲棲]
Linux 線程掛起與喚醒功能 實例
pthread_cond_wait
多線程的條件變量
條件變量是利用線程間共享的全局變量進行同步的一種機製,主要包括兩個動作:一個線程等待"條件變量的條件成立"而掛起;另一個線程使"條件成立"(給出條件成立信號)。為了防止競爭,條件變量的使用總是和一個互斥鎖結合在一起。
創建和注銷
pthread_cond_t cond=PTHREAD_COND_INITIALIZER
動態方式調用pthread_cond_init()函數,API定義如下:
int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr)
盡管POSIX標準中為條件變量定義了屬性,但在LinuxThreads中沒有實現,因此cond_attr值通常為NULL,且被忽略。
等待和激發
int
pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
在調用pthread_cond_wait()前必須由本線程加鎖(pthread_mutex_lock()),而在更新條件等待隊列以前,mutex保持鎖定狀態,並在線程掛起進入等待前解鎖。在條件滿足從而離開pthread_cond_wait()之前,mutex將被重新加鎖,以與進入pthread_cond_wait()前的加鎖動作對應。
pthread_cond_signal()激活一個等待該條件的線程,存在多個等待線程時按入隊順序激活其中一個
/* *主線程創建子線程(當前子線程為stop停止狀態),5秒後主線程喚醒子線程, *10秒後主線程掛起子線程。15秒後主線程再次喚醒子線程,20秒後主線程執行完畢, *等待子線程退出。 */ #include <stdio.h> #include <string.h> #include <pthread.h> #define RUN 1 #define STOP 0 pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t cond = PTHREAD_COND_INITIALIZER; int status = STOP; void *thread_function(void) { static int i = 0; while(1) { pthread_mutex_lock(&mut); while(!status) { pthread_cond_wait(&cond, &mut); } pthread_mutex_unlock(&mut); printf("child pthread %d\n", i++); if (i == 20) { break; } sleep(1); } } void thread_resume() { if (status == STOP) { pthread_mutex_lock(&mut); status = RUN; pthread_cond_signal(&cond); printf("pthread run!\n"); pthread_mutex_unlock(&mut); } else { printf("pthread run already\n"); } } void thread_pause() { if (status == RUN) { pthread_mutex_lock(&mut); status = STOP; printf("thread stop!\n"); pthread_mutex_unlock(&mut); } else { printf("pthread pause already\n"); } } int main() { int err; static int i = 0; pthread_t child_thread; if (pthread_mutex_init(&mut, NULL) != 0) { printf("mutex init error\n"); } if (pthread_cond_init(&cond, NULL) != 0) { printf("cond init error\n"); } err = pthread_create(&child_thread,NULL,(void *)thread_function,NULL); if (err != 0) { printf("can't create thread:%s\n", strerror(err)); } while(1) { printf("father pthread %d\n", i++); sleep(1); if (i == 5) { thread_resume(); } if (i == 10) { thread_pause(); } if (i == 15) { thread_resume(); } if (i == 20) { break; } } if (0 == pthread_join(child_thread, NULL)) { printf("child thread is over\n"); } return 0; }
最後更新:2017-04-03 12:56:08