❶ 條件變數的創建
條件變數和互斥鎖一樣,都有靜態和動態兩種創建方式,靜態方式使用PTHREAD_COND_INITIALIZER常量進行初始化,如下:
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,且被忽略。
❷ 怎麼使用pthread
一 概述
Pthread是一套通用的線程庫, 它廣泛的被各種Unix所支持, 是由POSIX提出的. 因此, 它具有很好的可移植性.
例1:
/* ------ test.c ------- */
#include <pthread.h>
void *pp(void *arg)
{
printf("%s\n", (char *)arg);
sleep(2);
}
return NULL;
}
main()
{
printf("I am main thread\n");
sleep(1);
}
}
執行:
gcc test.c -lpthread
./a.out
輸出:
I am main thread
hello world
I am main thread
hello world
............
二 返回值
也應該看到了, 每一個線程的返回值是void *.
有兩種方法返回:
1 return pointer;
2 pthread_exit(pointer);
這兩種方法是一樣的.
那麼, 其他的線程是如何得到這個返回值的呢?
用這個函數:
int pthread_join(pthread_t TH, void **thread_RETURN);
一個線程有兩種狀態, joinable 即系統保留線程的返回值, 直到有另外一個線程將它取走. detach系統不保留返回值.
下面的函數用於detach:
int pthread_detach (pthread_t TH);
pthread_t pthread_self(); 可以返回自己的id. 通常, 我們用下列的語句來detach自己:
pthread_detach(pthread_self());
三 Mutex
Mutex用於解決互斥問題. 一個Mutex是一個互斥裝置, 用於保護臨界區和共享內存. 它有兩種狀態locked, unlocked. 它不能同時被兩個線程所擁有.
下面的函數用於處理Mutex:
初始化一個Mutex
int pthread_mutex_init (pthread_mutex_t *MUTEX, const pthread_mutexattr_t *MUTEXATTR);
鎖定一個Mutex
int pthread_mutex_lock (pthread_mutex_t *mutex));
試圖鎖定一個Mutex
int pthread_mutex_trylock (pthread_mutex_t *MUTEX);
結鎖一個Mutex
int pthread_mutex_unlock (pthread_mutex_t *MUTEX);
銷毀一個Mutext
int pthread_mutex_destroy (pthread_mutex_t *MUTEX);
它的鎖一共有三種: "fast", "recursive", or "error checking"
進行lock操作時:
如處於unlock狀態, lock它, 即排斥佔有。
在被其他線程lock的時候,
掛起當前線程, 直到被其他線程unlock
在已經被自己lock的時候,
"fast" 掛起當前線程.
"resursive" 成功並立刻返回當前被鎖定的次數
"error checking" 立刻返回EDEADLK
進行unlock操作時:
解鎖.
"fast" 喚醒第一個被鎖定的線程
"recursive" 減少lock數(這個數僅僅是被自己lock的, 不關其它線程的) 當lock數等於零的
時候, 才被unlock並喚醒第一個被鎖定的線程.
"error check" 會檢查是不是自己lock的, 如果不是返回EPERM. 如果是喚 醒第一個被鎖定的線程,
通常, 我們用一些靜態變數來初始化mutex.
"fast" `PTHREAD_MUTEX_INITIALIZER'
"recursive" `PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP'
"error check" `PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP'
注意: _NP 表示no portable不可移植
例如:
// "fast" type mutex
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
... ...
pthread_mutext_lock(&mutex);
fwrite(buffer, 1, strlen(buffer), file);
pthread_mutex_unlock(&mutex);
... ...
四 Condition Variable (條件變數)
也是一種用於同步的device. 允許一個進程將自己掛起等待一個條件變數被改變狀態.
有下列幾個函數:
int pthread_cond_init (pthread_cond_t *COND,pthread_condattr_t *cond_ATTR);
int pthread_cond_signal (pthread_cond_t *COND);
int pthread_cond_broadcast (pthread_cond_t *COND);
int pthread_cond_wait (pthread_cond_t *COND, pthread_mutex_t *MUTEX);
int pthread_cond_timedwait (pthread_cond_t *COND, pthread_mutex_t *MUTEX, const struct timespec *ABSTIME);
int pthread_cond_destroy (pthread_cond_t *COND);
我想看看名字就可以知道它們的用途了. 通常我們也使用靜態變數來初始化一個條件變數.
Example:
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_cond_signal 用於喚醒一個被鎖定的線程.
pthread_cond_broadcast 用於喚醒所有被鎖定的線程.
pthread_cond_wait 用於等待.
為了解決競爭問題(即一個線程剛要去wait而另一個線程已經signal了), 它要與一個mutex連用.
看一看下面的例子:
int x,y;
pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
//Waiting until X is greater than Y is performed as follows:
pthread_mutex_lock(&mut);
/**//* operate on x and y */
pthread_mutex_unlock(&mut);
pthread_cond_wait的執行過程如下:
1. 首先, 它unlock the mutex, then 掛起當前的線程.
2. 當被喚醒的時候, 它會lock the mutex.
這樣就保證了這是一個臨界區.
五 Thread-Specific Data (TSD)
說白了就是線程中使用的靜態變數. 大家可以很容易的理解為什麼使用靜態變數函數不是線程安全的(也就是它們一定要很小心的在線程中使用).
而使用靜態變數又是很方便的, 這就產生了 thread-specific data. 可以把它理解為一個指針數組, 但對於每個線程來說是唯一的.
Example:
int func()
{
char *p;
p = strp(thread-specific-data[1]);
... ...
}
void *pthread-1(void *arg)
{
... ...
func()
... ...
}
void *pthread-2(void *arg)
{
... ...
func()
... ...
}
不同的線程調用func產生的結果是不同的. 這只是個例子.
int pthread_key_create(pthread_key_t *KEY, void (*destr_function) (void *));
int pthread_key_delete(pthread_key_t KEY);
int pthread_setspecific(pthread_key_t KEY, const void *POINTER);
void * pthread_getspecific(pthread_key_t KEY);
TSD可以看成是一個void *的數組.
注意: pthread_key_delete只是釋放key佔用的空間, 你仍然需要釋放那個void *.
為了加深你的理解, 看一看下面的例子吧:
/* Key for the thread-specific buffer */
static pthread_key_t buffer_key;
/* Once-only initialisation of the key */
static pthread_once_t buffer_key_once = PTHREAD_ONCE_INIT;
{
pthread_once(&buffer_key_once, buffer_key_alloc);
pthread_setspecific(buffer_key, malloc(100));
}
{
return (char *) pthread_getspecific(buffer_key);
}
{
pthread_key_create(&buffer_key, buffer_destroy);
}
{
free(buf);
}
❸ pthread_cond_wait的介紹
條件變數是利用線程間共享的全局變數進行同步的一種機制,主要包括兩個動作:一個線程等待條件變數的條件成立而掛起;另一個線程使條件成立(給出條件成立信號)。為了防止競爭,條件變數的使用總是和一個互斥鎖結合在一起。
❹ pthread.h不屬於linux內核,但是為什麼很多內核源碼中include了pthread.h
加入頭文件,是聲明這個函數是被定義過的,就如同要使用stdio.h里的函數一樣,沒有stdio.h頭文件,stdio.h里的函數一樣不可用;使用#include<pthread.h>後,裡面的函數就可以使用了,但是在編譯的時候就需要加上"-lpthread",以方便程序去尋找lpthread.so共享庫,例如:gcc abc.c -o abc -lpthread
❺ 既然pthread可以用mutex來lock/unlock,為什麼還要引入pthread
讀寫鎖有現成的,不過也可以自己用mutex實現一個,條件變數是一種同步機制, 比如不用忙等:
#include <pthread.h>
int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr);
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
❻ pthread 條件變數用在什麼地方
使用條件變數最大的好處是可以避免忙等。相當與多線程中的信號。 條件變數是線程中的東西就是等待某一條件的發生和信號一樣 以下是說明 ,條件變數使我們可以睡眠等待某種條件出現。 條件變數是利用線程間共享的全局變數進行同步的一種機制
❼ pthread 條件變數 調度
broadcast喚醒全部,signal喚醒一個,默認的調度看不了
❽ 嵌入式系統多線程編程中pthread_create、pthread_cond_wait等函數的源代碼在哪兒找
差別很大,都不一樣。
此外wince快要淘汰了,不要想了。
我可以幫助你,你先設置我最佳答案後,我網路Hii教你。
❾ 對libpthread.so反匯編後怎麼查看相應的源碼
對libpthread.so反匯編後怎麼查看相應的源碼
1:先找出libpthread.so.0在那用whereis 命令
# whereis libphread.so.0
2:再用rpm -q查詢
#rpm -qf libpthread.so.0的路徑
3:知道屬於哪個RPM包之後,掛載你的ISO 文件吧!假設你的ISO文件在/mnt/WinE下,准備掛載到/mnt/iso下
#mount -t iso9660 /mnt/WinE/xxxx.iso /mnt/iso/
4:去找那個RPM包吧,安裝就OK了!
❿ 如何使用 linux下多線程中條件變數
使用條件變數最大的好處是可以避免忙等。相當與多線程中的信號。
條件變數是線程中的東西就是等待某一條件的發生和信號一樣
以下是說明
,條件變數使我們可以睡眠等待某種條件出現。
條件變數是利用線程間共享的全局變數進行同步的一種機制,主要包括兩個動作:一個線程等待」條件變數的條件成立」而掛起;另一個線程使」條件成立」(給出條件成立信號)。為了防止競爭,條件變數的使用總是和一個互斥鎖結合在一起。
條件變數類型為pthread_cond_t
創建和注銷
條件變數和互斥鎖一樣,都有靜態動態兩種創建方式,靜態方式使用PTHREAD_COND_INITIALIZER常量,如下:
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,且被忽略。
注銷一個條件變數需要調用pthread_cond_destroy(),只有在沒有線程在該條件變數上等待的時候才能注銷這個條件變數,否則返回EBUSY。API定義如下:
int pthread_cond_destroy(pthread_cond_t *cond)
等待和激發
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime)
等待條件有兩種方式:無條件等待pthread_cond_wait()和計時等待pthread_cond_timedwait(),其中計時等待方式如果在給定時刻前條件沒有滿足,則返回ETIMEOUT,結束等待,其中abstime以與time()系統調用相同意義的絕對時間形式出現,0表示格林尼治時間1970年1月1日0時0分0秒。
使用絕對時間而非相對時間的優點是。如果函數提前返回(很可能因為捕獲了一個信號,)
無論哪種等待方式,都必須和一個互斥鎖配合,以防止多個線程同時請求pthread_cond_wait()(或pthread_cond_timedwait(),下同)的競爭條件(Race Condition)。mutex互斥鎖必須是普通鎖(PTHREAD_MUTEX_TIMED_NP)或者適應鎖(PTHREAD_MUTEX_ADAPTIVE_NP),且在調用pthread_cond_wait()前必須由本線程加鎖(pthread_mutex_lock()),而在更新條件等待隊列以前,mutex保持鎖定狀態,並在線程掛起進入等待前解鎖。在條件滿足從而離開pthread_cond_wait()之前,mutex將被重新加鎖,以與進入pthread_cond_wait()前的加鎖動作對應。
激發條件有兩種形式,pthread_cond_signal()激活一個等待該條件的線程,存在多個等待線程時按入隊順序激活其中一個;而pthread_cond_broadcast()則激活所有等待線程。
其他
pthread_cond_wait()和pthread_cond_timedwait()都被實現為取消點,因此,在該處等待的線程將立即重新運行,在重新鎖定mutex後離開pthread_cond_wait(),然後執行取消動作。也就是說如果pthread_cond_wait()被取消,mutex是保持鎖定狀態的,因而需要定義退出回調函數來為其解鎖。