導航:首頁 > 編程系統 > linux線程傳遞參數

linux線程傳遞參數

發布時間:2024-10-31 08:38:21

linux系統下進程通信的6種方式分別是什麼它們的區別在什麼地方線程通信有幾種方式這是很多人的疑問

管道:管道是一種半雙工的通信方式,數據只能單向流動,而且只能在具有親緣關系的進程間使用。進程的親緣關系通常是指父子進程關系。

信號量 :信號量是一個計數器,可以用來控制多個進程對共享資源的訪問。它常作為一種鎖機制,防止某進程正在訪問共享資源時,其他進程也訪問該資源。因此,主要作為進程間以及同一進程內不同線程之間的同步手段。

消息隊列:消息隊列是由消息的鏈表,存放在內核中並由消息隊列標識符標識。消息隊列克服了信號傳遞信息少、管道只能承載無格式位元組流以及緩沖區大小受限等缺點。

信號 :
信號是一種比較復雜的通信方式,用於通知接收進程某個事件已經發生。
共享內存:共享內存就是映射一段能被其他進程所訪問的內存,這段共享內由一個進程創建,多個進程都可以訪問。共享內存是最快的IPC 方式,
它是針對其他進程間通信方式運行效率低而專門設計的。它往往與其他通信機制,如信號量,合使用,來實現進程間的同步和通信。

套接字: 套解口也是一種進程間通信機制,與其他通信機制不同的是,它可用於不同及其間的進程通信

管道可以用於shell重定向,也就是命令管道類似grep
命名管道可以實現通信,通過makefifo傳遞消息
消息隊列也可以實現通信,不過相比命名管道有消息過濾的好處
信號其實就是KILL的應用
信號量是對臨界共享資源的合理調度
共享內存, 就是字面意思共享的內存

而線程通信方式有:互斥鎖,條件變數,讀寫鎖

㈡ Linux 多線程全面解析

在Unix的傳統模型中,當一個進程需要另一個實體執行某件事時,它會派生一個子進程。多數Unix網路伺服器程序都採用這種方式:父進程接受連接,派生子進程,子進程處理與客戶的交互。

盡管這種方法多年來表現良好,但fork操作存在一些問題。首先,fork操作成本高昂。它需要將內存映像從父進程復制到子進程,以及復制所有描述字等。即使有一些優化技術,如寫時拷貝(-on-write),fork操作仍然很昂貴。其次,fork後的子進程需要通過進程間通信(IPC)與父進程傳遞信息,這比傳遞信息要復雜得多。

線程可以解決這兩個問題。線程通常被稱為輕量級進程(lightweight process),因為它們比進程「輕量」。一般來說,創建一個線程要比創建一個進程快10~100倍。線程共享進程的全局內存,這使得它們很容易共享信息,但也帶來了同步問題。

一個進程中的所有線程不僅共享全局變數,還共享進程指令、大多數數據、打開的文件(如描述字)、信號處理程序和信號處置、當前工作目錄、用戶ID和組ID。但是每個線程有自己的線程ID、寄存器集合(包括程序計數器和棧指針)、棧(用於存放局部變數和返回地址)、error、信號掩碼、優先順序。在Linux中,線程編程符合Posix.1標准,稱為Pthreads。所有的pthread函數都以pthread_開頭,調用前均要包含pthread.h頭文件,並使用libpthread函數庫。

1.線程基礎介紹:
數據結構:

操作函數:

同步函數:

2.概念:
線程的組成部分:

3.線程定義
pthread_t pthread_ID 用於標識一個線程,其數據類型是pthread_t(常常是unsigned int)。pthread_equal函數用於比較兩個pthread_t是否相等,pthread_self函數用於獲得本線程的thread id。

4.線程的創建
創建線程調用pthread_create函數,參數說明:一個進程中的每個線程都由一個線程ID(thread ID)標識,其數據類型是pthread_t。每個線程都有許多屬性,如優先順序、起始棧大小、是否應該是一個守護線程等。當創建線程時,我們可通過初始化一個pthread_attr_t變數來覆蓋這些屬性。最後,我們要說明一個它將執行的函數。線程以調用該函數開始,然後或者顯式地終止(調用pthread_exit)或者隱式地終止(讓該函數返回)。函數的地址由func參數指定,該函數的調用參數是一個指針arg。調用成功返回0,出錯時返回正Exxx值。

5.線程的退出
exit, _Exit, _exit用於中止當前進程,而非線程。中止線程有三種方式:pthread_exit和pthread_join函數的用法,pthread_cancel函數,pthread_cleanup_push和pthread_cleanup_pop函數。

6.線程同步
互斥量:Mutex,讀寫鎖:Reader-Writer Locks,條件變數:pthread_cond_t。

7.線程屬性
線程屬性設置,包括綁定、分離狀態、堆棧地址、堆棧大小、優先順序等。

㈢ Linux線程及同步

linux多線程
1.線程概述
線程是一個進程內的基本調度單位,也可以稱為輕量級進程。線程是在共享內存空間中並發的多道執行路徑,它們共享一個進程的資源,如文件描述和信號處理。因此,大大減少了上下文切換的開銷。一個進程可以有多個線程,也就
是有多個線程式控制製表及堆棧寄存器,但卻共享一個用戶地址空間。
2.線程實現
線程創建pthread_create()
所需頭文件#include
<pthread.h>
函數原型int
pthread_create
((pthread_t
*thread,
pthread_attr_t
*attr,
thread:線程標識符
attr:線程屬性設置
start_routine:線程函數的起始地址
arg:傳遞給start_routine的參數
函數返回值
成功:0
出錯:-1
線程退出pthread_exit();
所需頭文件#include
<pthread.h>
函數原型void
pthread_exit(void
*retval)
函數傳入值retval:pthread_exit()調用者線程的返回值,可由其他函數如pthread_join
來檢索獲取
等待線程退出並釋放資源pthread_join()
所需頭文件#include
<pthread.h>
函數原型int
pthread_join
((pthread_t
th,
void
**thread_return))
函數傳入值
th:等待線程的標識符
thread_return:用戶定義的指針,用來存儲被等待線程的返回值(不為NULL時)
函數返回值
成功:0
出錯:-1
代碼舉例
1.
#include<pthread.h>
2.
#include<stdio.h>
3.
#include<errno.h>
4.
5.
/*線程1*/
6.
void
thread1()
7.
{
8.
int
i=0;
9.
10.
while(1)
11.
{
12.
printf(thread1:%d/n,i);
13.
if(i>3)
14.
pthread_exit(0);
15.
i++;
16.
sleep(1);
17.
}
18.
}
19.
20.
/*線程2*/
21.
void
thread2()
22.
{
23.
int
i=0;
24.
25.
while(1)
26.
{
27.
printf(thread2:%d/n,i);
28.
if(i>5)
29.
pthread_exit(0);
30.
i++;
31.
sleep(1);
32.
}
33.
}
34.
35.
int
main()
36.
{
37.
pthread_t
t1,t2;
38.
39.
/*創建線程*/
40.
pthread_create(&t1,NULL,(void
*)thread1,NULL);
41.
pthread_create(&t2,NULL,(void
*)thread2,NULL);
42.
/*等待線程退出*/
43.
pthread_join(t1,NULL);
44.
pthread_join(t2,NULL);
45.
return
0;
46.
}
3同步與互斥
<1>互斥鎖
互斥鎖的操作主要包括以下幾個步驟。

互斥鎖初始化:pthread_mutex_init

互斥鎖上鎖:pthread_mutex_lock

互斥鎖判斷上鎖:pthread_mutex_trylock

互斥鎖接鎖:pthread_mutex_unlock

消除互斥鎖:pthread_mutex_destroy
1.
#include<pthread.h>
2.
#include<stdio.h>
3.
#include<errno.h>
4.
5.
int
i=0;/*共享變數*/
6.
pthread_mutex_t
mutex=PTHREAD_MUTEX_INITIALIZER;/*互斥鎖*/
7.
8.
void
thread1()
9.
{
10.
int
ret;
11.
while(1)
12.
{
13.
14.
15.
ret=pthread_mutex_trylock(&mutex);/*判斷上鎖*/
16.
17.
if(ret!=EBUSY)
18.
{
19.
pthread_mutex_lock(&mutex);/*上鎖*/
20.
printf(This
is
thread1:%d/n,i);
21.
i++;
22.
pthread_mutex_unlock(&mutex);/*解鎖*/
23.
}
24.
sleep(1);
25.
}
26.
}
27.
28.
void
thread2()
29.
{int
ret;
30.
while(1)
31.
{
32.
33.
ret=pthread_mutex_trylock(&mutex);
34.
if(ret!=EBUSY)
35.
{
36.
pthread_mutex_lock(&mutex);
37.
printf(This
is
thread2:%d/n,i);
38.
i++;
39.
pthread_mutex_unlock(&mutex);
40.
}
41.
sleep(1);
42.
}
43.
}
44.
int
main()
45.
{
46.
pthread_t
t1,t2;
47.
pthread_mutex_init(&mutex,NULL);
48.
pthread_create(&t1,NULL,(void
*)thread1,NULL);
49.
pthread_create(&t2,NULL,(void
*)thread2,NULL);
50.
51.
pthread_join(t1,NULL);
52.
pthread_join(t2,NULL);
53.
54.
pthread_mutex_destroy(&mutex);
55.
return
0;
56.
}
<2>信號量
未進行同步處理的兩個線程
1.
#include<pthread.h>
2.
#include<stdio.h>
3.
#include<errno.h>
4.
5.
int
i=0;
6.
void
thread1()
7.
{
8.
9.
while(1)
10.
{
11.
printf(This
is
thread1:%d/n,i);
12.
i++;
13.
sleep(1);
14.
}
15.
}
16.
17.
18.
void
thread2()
19.
{
20.
21.
while(1)
22.
{
23.
printf(This
is
thread2:%d/n,i);
24.
i++;
25.
sleep(1);
26.
}
27.
}
28.
29.
int
main()
30.
{
31.
pthread_t
t1,t2;
32.
33.
pthread_create(&t1,NULL,(void
*)thread1,NULL);
34.
pthread_create(&t2,NULL,(void
*)thread2,NULL);

㈣ linux下線程屬性常用操作有哪些

LinuxThread的線程機制

LinuxThreads是目前平台上使用最為廣泛的線程庫,由Xavier Leroy ([email protected]) 負責開發完成,並已綁定在GLIBC中發行。它所實現的就是基於核心輕量級進程的"一對一"線程模型,一個線程實體對應一個核心輕量級進程,而線程之間的 管理在核外函數庫中實現。

1.線程描述數據結構及實現限制

LinuxThreads定義了一個struct _pthread_descr_struct數據結構來描述線程,並使用全局數組變數 __pthread_handles來描述和引用進程所轄線程。在__pthread_handles中的前兩項,LinuxThreads定義了兩個全 局的系統線程:__pthread_initial_thread和__pthread_manager_thread,並用 __pthread_main_thread表徵__pthread_manager_thread的父線程(初始為 __pthread_initial_thread)。

struct _pthread_descr_struct是一個雙環鏈表結構,__pthread_manager_thread所在的鏈表僅包括它 一個元素,實際上,__pthread_manager_thread是一個特殊線程,LinuxThreads僅使用了其中的errno、p_pid、 p_priority等三個域。而__pthread_main_thread所在的鏈則將進程中所有用戶線程串在了一起。經過一系列 pthread_create()之後形成的__pthread_handles數組將如下圖所示:

圖2 __pthread_handles數組結構

新創建的線程將首先在__pthread_handles數組中占據一項,然後通過數據結構中的鏈指針連入以__pthread_main_thread為首指針的鏈表中。這個鏈表的使用在介紹線程的創建和釋放的時候將提到。

LinuxThreads遵循POSIX1003.1c標准,其中對線程庫的實現進行了一些范圍限制,比如進程最大線程數,線程私有數據區大小等等。在 LinuxThreads的實現中,基本遵循這些限制,但也進行了一定的改動,改動的趨勢是放鬆或者說擴大這些限制,使編程更加方便。這些限定宏主要集中 在sysdeps/unix/sysv/linux/bits/local_lim.h(不同平台使用的文件位置不同)中,包括如下幾個:

每進程的私有數據key數,POSIX定義_POSIX_THREAD_KEYS_MAX為128,LinuxThreads使用 PTHREAD_KEYS_MAX,1024;私有數據釋放時允許執行的操作數,LinuxThreads與POSIX一致,定義 PTHREAD_DESTRUCTOR_ITERATIONS為4;每進程的線程數,POSIX定義為64,LinuxThreads增大到1024 (PTHREAD_THREADS_MAX);線程運行棧最小空間大小,POSIX未指定,LinuxThreads使用 PTHREAD_STACK_MIN,16384(位元組)。

2.管理線程

"一對一"模型的好處之一是線程的調度由核心完成了,而其他諸如線程取消、線程間的同步等工作,都是在核外線程庫中完成的。在LinuxThreads 中,專門為每一個進程構造了一個管理線程,負責處理線程相關的管理工作。當進程第一次調用pthread_create()創建一個線程的時候就會創建 (__clone())並啟動管理線程。

在一個進程空間內,管理線程與其他線程之間通過一對"管理管道(manager_pipe[2])"來通訊,該管道在創建管理線程之前創建,在成功啟動 了管理線程之後,管理管道的讀端和寫端分別賦給兩個全局變數__pthread_manager_reader和 __pthread_manager_request,之後,每個用戶線程都通過__pthread_manager_request向管理線程發請求, 但管理線程本身並沒有直接使用__pthread_manager_reader,管道的讀端(manager_pipe[0])是作為__clone ()的參數之一傳給管理線程的,管理線程的工作主要就是監聽管道讀端,並對從中取出的請求作出反應。

創建管理線程的流程如下所示:
(全局變數pthread_manager_request初值為-1)

圖3 創建管理線程的流程

初始化結束後,在__pthread_manager_thread中記錄了輕量級進程號以及核外分配和管理的線程id, 2*PTHREAD_THREADS_MAX+1這個數值不會與任何常規用戶線程id沖突。管理線程作為pthread_create()的調用者線程的 子線程運行,而pthread_create()所創建的那個用戶線程則是由管理線程來調用clone()創建,因此實際上是管理線程的子線程。(此處子 線程的概念應該當作子進程來理解。)

__pthread_manager()就是管理線程的主循環所在,在進行一系列初始化工作後,進入while(1)循環。在循環中,線程以2秒為 timeout查詢(__poll())管理管道的讀端。在處理請求前,檢查其父線程(也就是創建manager的主線程)是否已退出,如果已退出就退出 整個進程。如果有退出的子線程需要清理,則調用pthread_reap_children()清理。

然後才是讀取管道中的請求,根據請求類型執行相應操作(switch-case)。具體的請求處理,源碼中比較清楚,這里就不贅述了。

3.線程棧

在LinuxThreads中,管理線程的棧和用戶線程的棧是分離的,管理線程在進程堆中通過malloc()分配一個THREAD_MANAGER_STACK_SIZE位元組的區域作為自己的運行棧。

用戶線程的棧分配辦法隨著體系結構的不同而不同,主要根據兩個宏定義來區分,一個是NEED_SEPARATE_REGISTER_STACK,這個屬 性僅在IA64平台上使用;另一個是FLOATING_STACK宏,在i386等少數平台上使用,此時用戶線程棧由系統決定具體位置並提供保護。與此同 時,用戶還可以通過線程屬性結構來指定使用用戶自定義的棧。因篇幅所限,這里只能分析i386平台所使用的兩種棧組織方式:FLOATING_STACK 方式和用戶自定義方式。

在FLOATING_STACK方式下,LinuxThreads利用mmap()從內核空間中分配8MB空間(i386系統預設的最大棧空間大小,如 果有運行限制(rlimit),則按照運行限制設置),使用mprotect()設置其中第一頁為非訪問區。該8M空間的功能分配如下圖:

圖4 棧結構示意

低地址被保護的頁面用來監測棧溢出。

對於用戶指定的棧,在按照指針對界後,設置線程棧頂,並計算出棧底,不做保護,正確性由用戶自己保證。

不論哪種組織方式,線程描述結構總是位於棧頂緊鄰堆棧的位置。

4.線程id和進程id

每個LinuxThreads線程都同時具有線程id和進程id,其中進程id就是內核所維護的進程號,而線程id則由LinuxThreads分配和維護。

閱讀全文

與linux線程傳遞參數相關的資料

熱點內容
matlab怎麼調試程序 瀏覽:2
winxp升級win7的危害 瀏覽:496
網路沒連上卻不可用是怎麼回事 瀏覽:752
社區版本 瀏覽:738
怎麼查微信公眾號什麼時候開通的 瀏覽:717
安裝三菱編程閃退怎麼回事 瀏覽:488
手機怎麼創建word文件格式 瀏覽:694
c語言連接資料庫 瀏覽:887
數據線粉色和白色哪個是正 瀏覽:775
vb編程應注意什麼 瀏覽:855
js循環添加控制項 瀏覽:615
學習計算機網路的作用 瀏覽:235
access資料庫最新內容怎麼調 瀏覽:203
上古世紀新版本跑商 瀏覽:267
iphone5國際漫遊設置 瀏覽:107
ipodwatch如何安裝app 瀏覽:114
誰有微信搶紅包的群號 瀏覽:872
word07頁碼從任意頁開始 瀏覽:791
js禁止滑動事件 瀏覽:800
蘋果查序號怎麼看不是 瀏覽:61

友情鏈接