Linux c 多執行緒問題

2021-09-25 03:20:05 字數 3493 閱讀 1659

因專案問題,最近涉及到一些跟執行緒相關的知識,總結一下 大家互相進步。

在傳統的unix模型中,當乙個程序需要由另乙個實體執行某件事時,該程序派生(fork)乙個子程序,讓子程序去進行處理。unix下的大多數網路伺服器程式都是這麼編寫的,即父程序接受連線,派生子程序,子程序處理與客戶的互動。

雖然這種模型很多年來使用得很好,但是fork時有一些問題:

執行緒有助於解決這兩個問題。執行緒有時被稱為輕權程序(lightweight process),因為執行緒比程序「輕權」,一般來說,建立乙個執行緒要比建立乙個程序快10~100倍。

乙個程序中的所有執行緒共享相同的全域性記憶體,這使得執行緒很容易共享資訊,但是這種簡易性也帶來了同步問題。

乙個程序中的所有執行緒不僅共享全域性變數,而且共享:程序指令、大多數資料、開啟的檔案(如描述字)、訊號處理程式和訊號處置、當前工作目錄、使用者id和組id。但是每個執行緒有自己的執行緒id、暫存器集合(包括程式計數器和棧指標)、棧(用於存放區域性變數和返回位址)、error、訊號掩碼、優先順序。在linux中線程程式設計符合posix.1標準,稱為pthreads。所有的pthread函式都以pthread_開頭。在呼叫它們前均要包括pthread.h標頭檔案,乙個函式庫libpthread.a來實現。

執行緒的屬性

執行緒屬性結構為pthread_attr_t,在標頭檔案/usr/include/pthread.h中定義。初始化的函式為pthread_attr_init,這個函式必須在pthread_create函式之前呼叫。屬性物件主要包括是否繫結、是否分離、堆疊位址、堆疊大小、優先順序。預設的屬性為非繫結、非分離、預設1m的堆疊、與父程序同樣級別的優先順序。

設定執行緒繫結狀態的函式為pthread_attr_setscope,它有兩個引數,第乙個是指向屬性結構的指標,第二個是繫結型別,它有兩個取值:pthread_scope_system(繫結的)和pthread_scope_process(非繫結的)。下面的**即建立了乙個繫結的執行緒。  

輕程序(lwp:light weight process)。輕程序可以理解為核心執行緒,它位於使用者層和系統層之間。系統對執行緒資源的分配、對執行緒的控制是通過輕程序來實現的,乙個輕程序可以控制乙個或多個執行緒。。     

執行緒的分離狀態決定乙個執行緒以什麼樣的方式來終止自己。原有的執行緒等待建立的執行緒結束。只有當pthread_join()函式返回時,建立的執行緒才算終止,才能釋放自己占用的系統資源。分離執行緒不是這樣子的,它沒有被其他的執行緒所等待,自己執行結束了,執行緒也就終止了,馬上釋放系統資源。程式設計師應該根據自己的需要,選擇適當的分離狀態。設定執行緒分離狀態的函式為pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)。第二個引數可選為pthread_create_detached(分離執行緒)和 pthread _create_joinable(非分離執行緒

優先順序的設定一般為先獲取在修改,修改執行緒優先順序需要注意到建立程序的型別。

sched_other 表示 建立的普通程序。

sched_fifo&&sched_rr表示建立的可修改優先順序的執行緒,高優先順序會搶占低優先順序。 

前者,高優先順序執行期間,低優先順序沒法搶占,只能等到高優先順序主動退出;對於同等優先順序,先執行的程序會一直佔據cpu, 只有等到先執行的程序主動退出,後續程序才能得到時間片。

後者,高優先順序會搶占低優先順序,高優先順序執行期間,低優先順序沒法搶占,只能等到高優先順序主動退出, ;對於同等優先順序的程序,各個程序會輪流執行一定的時間片(大約100ms)。

/*

* threadtest.cpp

* * created on: jul 10, 2019

* author: dy

*///#include "../core/thread.h"

#include #include #include #include #include #include using namespace std;

extern "c" void* thread2 (void*);

extern "c" void* thread1 (void*);

void* thread1(void*)

printf("thread 1\n");}

}void* thread2(void*)

printf("thread 2\n");}

}int main()

程式執行過程**現了問題 g++編譯過程中會報如下錯誤: error: invalid conversion from 『void (*)(void*)』 to 『void* (*)(void*)』 [-fpermissive]。究其原因可能是c語言編譯器允許隱含性的將乙個通用指標轉換為任意型別的指標,而在c++中不允許的。原因是pthread_create()中的第三個引數是載入乙個函式,這個函式有乙個引數可以傳入,返回乙個通用指標。

因此,出現上述錯誤的解決方法:1)執行緒函式定義為void  thread(void* ),而呼叫處寫為:int ret = pthread_create(&id, &attr, (viod*)&thread, null);2)執行緒函式定義為void * thread1(void* ),呼叫處為:int ret = pthead_create(&id, &attr, thread1, null)。然後進行編譯。

執行緒建立

//建立執行緒成功時,函式返回 0,若返回值不為 0 則說明建立執行緒失敗。

//函式原型:

int pthread_create(pthread_t *restrict tidp,

const pthread_attr_t *restrict attr,

void *(*start_rtn)(void),void *restrict arg);

//形式引數:

//pthread_t *restrict tidp 要建立的執行緒的執行緒id指標,建立成功後,指向的記憶體存放建立執行緒的id;

//const pthread_attr_t *restrict attr乙個不透明的屬性物件,具體見上文屬性的建立;

//void* (start_rtn)(void)返回值是void型別的指標函式;執行緒函式的起始位址,執行緒一旦建立立馬執行;

//void* restrict arg start_rtn的形參;

//返回值:若是成功建立執行緒返回0,否則返回錯誤的編號。

int ret = pthread_create (thread, attr, start_routine, arg);

執行緒掛起

函式原型:int pthread_join( pthread_t thread, void **value_ptr);

引數說明如下:thread等待退出執行緒的執行緒號;value_ptr退出執行緒的返回值。該函式的作用使得當前執行緒掛起,等待另乙個執行緒返回才繼續執行。也就是說當程式執行到這個地方時,程式會先停止,然後等執行緒id為thread的這個執行緒返回,然後程式才會斷續執行。

執行緒終止

函式原型:int pthread_exit(void *rval_pt)

引數說明如下:

linux C 多執行緒

標頭檔案 include 執行緒建立 pthread create 執行緒退出 pthread exit 互斥鎖 pthread mutex init pthread mutex lock pthread mutex unlock void thread function void arg if 0...

linux C 多執行緒程式設計

1.solaris vs.linux posix 庫 solaris 庫 lib 執行緒 linux posix 庫 libp 執行緒 操作sema destroy sem destroy 銷毀訊號狀態。sema init sem init 初始化訊號。sema post sem post 增加訊號...

linux C 多執行緒程式設計

1.solaris vs.linux posix 庫 solaris 庫 lib 執行緒 linux posix 庫 libp 執行緒 操作sema destroy sem destroy 銷毀訊號狀態。sema init sem init 初始化訊號。sema post sem post 增加訊號...