pthread執行緒使用小結
1.奇怪的執行緒引數初始化
for( i=0; i//會有什麼問題?
pthread_create(&tid,null, &thread_client_function, (void*)&i );
上面**應該很容易明白,建立多個執行緒,傳入序列號作為執行緒id。基實這裡存在乙個大bug, 傳遞的引數會不成功!!
示例**:
view plain
copy to clipboard
print?
#include
#include
#include
#include
#include
void
* thread_client_function(
void
* param )
intmain(
intargc,
char
* argv )
pthread_join( tid, null );
return
0;
} 輸出:gcc -o test_thread test_thread.c -lpthread
./test_thread 3
client id 3
client id 3
client id 3
為什麼呢?注意其實傳遞時i是區域性變數,而執行緒的建立是有延時的,所以當多次呼叫時,執行緒函式還沒執行。但是這裡i已經為3了。當執行緒函式開始執行,讀入的引數自然都為3了,這個小細節真可謂令我大傷腦筋呀:)
稍作修改即可:
int * a = (int*)malloc( n* sizeof(int) );
for( i=0; ia[i] = i;
pthread_create(&tid,null, &thread_client_function, (void*)&a[i] );
pthread_join( tid, null );
這樣就可以儲存引數不變了。
2. pthread_mutex_t / pthread_cond_t初始化/釋放
作為乙個全域性變數時可以使用:
pthread_mutex_t g_mtx = pthread_mutex_initializer;
pthread_cond_t g_cond = pthread_cond_initializer;
如果有多個可使用:
pthread_mutex_init( &g_mtx , null);
pthread_cond_init( &g_cond , null);
釋放:pthread_mutex_destroy( &g_mtx );
pthread_mutex_destroy( &g_mtx );
3. 同步條件pthread_cond_t使用
1)需要配合mutex使用
pthread_mutex_lock( &g_mtx );
pthread_cond_wait( &g_cond , &g_mtx );
pthread_mutex_unlock( &g_mtx );
使用pthread_cond_wait 需要在 lock/unlock 之間,以防止在進入wait狀態前有signal。需要先lock, 一旦進行wait狀態,會釋放 mutex的lock。而一旦有收到signal訊號就會自動重新獲到mutex的lock。而且cond的lock是原子操作。
在需要的地方進行 pthread_cond_signal( g_cond ), 之前的wait 位置就可以執行,達到多個執行緒同步。
2)使用超時條件
struct timespec tv;
tv.tv_sec = time(0) + 1;
tv.tv_nsec = 0;
ret = pthread_cond_timedwait( &g_cond , &g_mtx ,&tv );
指定超時結構體timespec,注意超時時間是當前時間,所以要設定為time(0) + n秒。timespec 可精確到納秒。
3)多個執行緒序列執行
只需要在全域性設定乙個處理序列號,這樣每個執行緒在執行前判斷是否為自己要處理的序號,否則繼續wait, 處理框架如下:
void* thread_client_function( void* param )
int client_id = *(int*)param;
dopthread_cond_wait( &g_conds[ i + 1 ] , &g_mtxs[i] ); //等待取得執行訊號
while ( g_do[client_id][i] != g_idx ); //判斷是否為當前處理序列,否則繼續等待
void* thread_server_function( void* param )
for(i=0;iprintf("server signal %d\n", i + 1 );
pthread_cond_signal( &g_conds[ i + 1 ] ); //喚醒多個處理執行緒
上面使用了多個cond的處理,也可以直接使用乙個cond, 使用pthread_cond_broadcast響醒所有等待的執行緒。
就是說pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)函式傳入的引數mutex用於保護條件,因為我們在呼叫pthread_cond_wait時,如果條件不成立我們就進入阻塞,但是進入阻塞這個期間,如果條件變數改變了的話,那我們就漏掉了這個條件。因為這個執行緒還沒有放到等待佇列上,所以呼叫pthread_cond_wait前要先鎖互斥量,即呼叫pthread_mutex_lock(),pthread_cond_wait在把執行緒放進阻塞佇列後,自動對mutex進行解鎖,使得其它執行緒可以獲得加鎖的權利。這樣其它執行緒才能對臨界資源進行訪問並在適當的時候喚醒這個阻塞的程序。當pthread_cond_wait返回的時候又自動給mutex加鎖。
執行緒鎖使用經驗
一.減少鎖的使用 鎖使用帶來如下效能損失 1.加鎖和解鎖操作,本身有一定的開銷 2.臨界區的 不能併發執行 3.入臨界區的次數過於頻繁,執行緒之間對臨界區的爭奪太過激烈,若執行緒競爭互斥量失敗,就會陷入阻塞,讓出 cpu,因此執行上下文切換的次數要遠遠多於不使用互斥量的 代替鎖的辦法有很多,如使用無...
Linux 的多執行緒程式設計的高效開發經驗
本文中我們針對 linux 上多執行緒程式設計的主要特性總結出 5 條經驗,用以改善 linux 多執行緒程式設計的習慣和避免其中的開發陷阱。在本文中,我們穿插一些 windows 的程式設計用例用以對比 linux 特性,以加深讀者印象。背景 linux 平台上的多執行緒程式開發相對應其他平台 比...
Linux經驗筆記
1.ubuntu系統安裝解壓軟體 sudo apt get install unrar 2.ubuntu系統更新 sudo apt get update 3.ubuntu修改使用者名稱密碼 sudo passwd jerry 4.重要熱鍵 tab 命令補全,檔案路徑補全 ctrl c 終止正在執行的...