在「一步步理解linux程序(1)–程序基礎知識」中我們介紹過:
核心並沒有執行緒這個概念。linux把所有的執行緒都當做程序來實現,執行緒僅僅被視為乙個與其他程序共享某些資源的程序。
下面關於執行緒的討論是基於posix的標準。
程序的id用pid_t
結構表示,類似的,執行緒的id用pthread_t
結構表示。具體的值可以 通過pthread_self
函式得到,pthread_t
之間的比較通過pthread_equal
函式實現。
#include pthread_t pthread_self(void);
int pthread_equal(pthread_t tid1, pthread_t tid2);
新執行緒使用pthread_create
函式建立:
#include int pthread_create(pthread_t *restirct tidp,
const pthread_attr_t *restrict attr,
void *(*start_rtn)(void), void *restrict arg);
/* 成功則返回0,出錯返回錯誤編號 */
引數解釋如下:
程序的終止有3種方式:
1. 從啟動時執行的函式中返回,返回值是執行緒的退出碼。 2. 執行緒呼叫pthread_exit
函式。 3. 被同一程序中的其他執行緒取消。
#include void pthread_exit(void *rval_ptr);
#include int pthread_join(pthread_t thread, void **rval_ptr);
呼叫執行緒將一直阻塞,直到指定的執行緒終止。
執行緒可以通過pthread_cancel
函式請求取消同一程序中的其他執行緒:
#include int pthread_cancel(pthread_t tid);
核心中的同步可以參考一步步理解linux之核心同步posix也定義了類似的同步方法。
互斥量用pthread_mutex_t資料型別表示,使用前需要初始化,可以通過把它設定為常量pthread_mutex_initializer
(只對靜態分配的互斥量)或者通過pthread_mutex_init
函式進行初始化。銷毀互斥量可以通過pthread_mutex_destroy
函式。
#include int pthread_mutex_init(pthread_mutex_t *restrict mutex,
const pthread_mutexattr_t *restrict attr);
int pthread_mutex_destroy(pthread_mutex_t *mutex);
引數attr
表示互斥量的引數,使用預設引數直接設定為null即可。
下面三個函式用於獲得互斥量和釋放互斥量:
#include int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
類似於核心中的「讀寫自旋鎖」,有可能導致寫程序的飢餓。主要的操作函式是:
#include 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);
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);
條件變數給多個執行緒提供了乙個匯合的場所,條件變數通過pthread_cond_t
結構表示, 它本身需要乙個互斥量進行保護。在等待的條件還沒有成立時,執行緒會被放到乙個佇列中 ,等到這個條件滿足時,可以選擇喚醒佇列中的乙個執行緒或者全部執行緒。
可以靜態地把乙個條件變數初始化為pthread_initializer
,也可以使用下面的函式初始 化和銷毀乙個條件變數:
#include int pthread_cond_init(pthread_cond_t *restrict cond,
pthread_cond_attr *restrict attr);
int pthread_cond_destroy(pthread_cond_t *cond);
下面兩個函式讓執行緒等待特定的條件變數,注意使用了乙個互斥量進行保護,其中後者有 乙個超時時間的引數,但超過這個時間後即使條件沒有成立也會返回。
#include int pthread_cond_wait(pthread_cond_t *restrict cond,
pthread_mutex_t *restrict mutex);
int pthread_cond_timewait(pthread_cond_t *restrict cond,
pthread_mutex_t *restrict mutex,
const struct timespec *restrict timeout);
下面兩個函式用於通知執行緒某個條件已經滿足:
#include int pthread_cond_signal(pthread_cond_t *cond);
int pthread_cond_broadcast(pthread_cond_t *cond);
其中pthread_cond_broadcast
會喚醒這個條件變數等待佇列上的所有執行緒,而pthread_cond_signal
只喚醒其中的乙個。
jh, 2013-05-15
一步步理解Linux程序(6) 執行緒
在 一步步理解linux程序 1 程序基礎知識 中我們介紹過 核心並沒有執行緒這個概念。linux把所有的執行緒都當做程序來實現,執行緒僅僅被視為乙個 與其他程序共享某些資源的程序。下面關於執行緒的討論是基於posix的標準。程序的id用pid t結構表示,類似的,執行緒的id用pthread t結...
一步步啟動linux
可以一步一步啟動linux.在ubantu剛一啟動時,按c健即進入grub 提示符狀態,在此狀態下輸入 我用的是ubuntu 13 grub linux vmlinuz grub ls boot grub initrd boot initrd.img 3.11.0 15 generic grub b...
一步步學ROS
最近因為看svo的 裡面用到catkin決定要好好看ros,年前學會基本操作。啟動節點 rosrun package name executable name 檢視節點 rosnode list 注 rosout 節點是乙個特殊的節點,通過 roscore 自動啟動 檢視特定節點的資訊 rosnod...