函式原型
#include
int pthread_create(pthread_t *restrict thread,
const pthread_attr_t *restrict attr,
void *(start_routine)(void), void *restrict arg);
建立執行緒的函式有四個引數,第乙個引數是乙個pthread_t型別的指標。第二個引數通常設定為null,第三個引數是新建立的執行緒的函式,返回型別為(void *),第四個引數為傳遞的引數,型別為(void *)型別。
下面給出乙個例項
#include
#include
#include
#include
#include
void * xiancheng(void *p)
int main()
xiancheng(「zhi」);
sleep(1);
}使用命令gcc pthreap.c - o pthreap -lpthreap進行編譯
在這裡我們需要注意到幾個點
我們建立執行緒使用的函式的第乙個引數id,我們傳遞的是乙個位址,這個引數的作用便是將這個執行緒的tid返回給id這個變數中。
這個函式的第三個引數是乙個函式的名字,表示乙個新建立的執行緒該執行的函式,這個函式的返回型別為(void *),因此我們在建立函式時應該使返回值為(void *)型別。
第四個引數中,我們傳遞乙個(void *)型別的變數給這個新的執行緒,因此我們在函式接收這個變數時應該宣告為(void *)型別。
pthread_t和pid_t的定義型別為 typedef unsigned pthread_t和typedef unsigned pid_t。
這個函式如果出錯,出錯的資訊不會儲存在errno中,而是這個函式的返回值,成功返回0。
結束子執行緒
執行緒的結束有幾種方式
使用pthread_exit來本結束執行緒
使用pthread_cancel來結束本程序的乙個執行緒,有乙個引數為被結束的執行緒的id
使用return來結束執行緒
下面我們來介紹一下執行緒的返回值
執行緒的返回值和結束執行緒的三種方式相對應,也是有三種
使用pthread_exit((void *)1)來進行結束,使用pthread_join函式來進行接收這個執行緒的返回值pthread_join(id,&a)其中a來接收1的值。a的定義為void * a;
使用return和上面的一樣
使用pthread_cancel來結束,會返回乙個巨集定義pthread_canceled,這個定義為-1。
下面進行乙個例項
#include
#include
#include
#include
#include
void * xiancheng(void *ar**)
void * xiancheng1(void *ar**)
void * xiancheng2(void *ar**)
int main()
結果:root@ubuntu:/home/sun/project# ./aa01
waitting 4s
waitting 4s
-1執行緒間的同步
當有多個執行緒同時訪問乙個共享變數時便會出現問題,可能並不是我們預期的結果出現,接下來我們分析一下原因。
**例項
#include
#include
#include
#include
int count=0;
void *pthread1(void * argc)
void *pthread2(void * argc)
int main()
執行**結果
在單核上執行結果
root@ubuntu:/home/sun/project# ./aa
200000root@ubuntu:/home/sun/project# ./aa
200000root@ubuntu:/home/sun/project# ./aa
200000root@ubuntu:/home/sun/project# ./aa
200000root@ubuntu:/home/sun/project# ./aa
200000root@ubuntu:/home/sun/project# ./aa
200000root@ubuntu:/home/sun/project# ./aa
200000root@ubuntu:/home/sun/project# ./aa
200000root@ubuntu:/home/sun/project# ./aa
200000root@ubuntu:/home/sun/project# ./aa
200000root@ubuntu:/home/sun/project# ./aa
200000root@ubuntu:/home/sun/project# ./aa
200000root@ubuntu:/home/sun/project#
在多核上執行結果
root@ubuntu:/home/sun/project# ./aa
111388root@ubuntu:/home/sun/project# ./aa
127061root@ubuntu:/home/sun/project# ./aa
108070root@ubuntu:/home/sun/project# ./aa
101543root@ubuntu:/home/sun/project# ./aa
141164root@ubuntu:/home/sun/project# ./aa
200000root@ubuntu:/home/sun/project# ./aa
129528root@ubuntu:/home/sun/project# ./aa
148950root@ubuntu:/home/sun/project# ./aa
122621root@ubuntu:/home/sun/project# ./aa
109718root@ubuntu:/home/sun/project# ./aa
157505root@ubuntu:/home/sun/project# ./aa
183777root@ubuntu:/home/sun/project#
分析可以看到我們使用多執行緒訪問乙個共享變數時在多核上回出現錯誤,我們分析一下出現錯誤的原因。
正常的程式執行順序
程式在執行時先從記憶體上取出資料到暫存器上
然後執行加1操作
再將資料存如記憶體
多執行緒也是以這樣的方式執行的,但是在多核上會同時執行這個程序的多個執行緒,比如執行緒1從記憶體取出a=5,開始執行a++操作執行10次,執行後a=15,執行緒2也開始執行a++操作,由於執行緒2在執行時執行緒1還沒有執行完,表示還沒有將15寫入記憶體,因此執行緒2取出a=5,因此執行緒2便會10次a++操作,執行完後a=15,將15寫入記憶體,因此執行緒1和執行緒2都會將15寫入記憶體,記憶體的最終結果為15,但是執行緒1和執行緒2一共執行了30次加法操作,因此便會出現小於預期結果的值。
多執行緒基本操作
1 繼承thread類建立執行緒 2 實現runnable介面建立執行緒 3 使用callable和future建立執行緒 1.實現callable介面,重寫call 方法,建立該實現類的例項 2.使用futuretask類來包裝callable物件,該futuretask物件封裝了callable...
多執行緒基本操作
在多執行緒中經常用到的關鍵字是lock。lock 關鍵字可確保當乙個執行緒位於 的臨界區時,另乙個執行緒不會進入該臨界區 所謂的臨界點指的是 當多個執行緒訪問乙個更改物件狀態的方法是,因為不知道到底要修改那個狀態,將產生不可預知的資料損壞 所以關於多執行緒的程式設計中找到程式的臨界區是很重要的事情。...
執行緒的基本操作 完
執行緒安全是多執行緒開發的根基,我們能夠使用volatile保證變數更新的資料其他執行緒能夠看到,但是如果兩個執行緒同時操作乙個資料,執行緒安全無法保證.下面的例子中,i的結果大概率小於我們預期的200000,原因就在於t1,t2同時獲取i值,先後寫入同乙個結果.public class sync ...