UNIX網路程式設計 執行緒(二十六)

2021-06-18 08:53:34 字數 2373 閱讀 6842

unix網路程式設計----執行緒

一、概述

乙個伺服器的父程序accept乙個連線,fork()乙個子程序,該子程序處理與該連線對端的客戶之間的通訊。但是fork呼叫卻存在一些問題。

1)  fork是昂貴的。當今的實現使用稱為寫實複製的技術,用以避免在子程序切實需要自己的副本之前把父程序的資料空間按複製到子程序。然而即便有這樣的優化措施,fork還是昂貴的。

2)  fork返回之後斧子程序之間資訊的傳遞需要程序間通訊(ipc)機制,從父程序向子程序傳遞資訊比較容易,但是相反的方向卻不是那麼容易。

執行緒有助於解決這兩個問題,執行緒建立可能比程序的建立塊10~100倍。

同一程序的所有執行緒共享相同的全域性記憶體。這使得執行緒之間易於共享資訊,然而伴隨這種簡易行而來的是同步問題

同一程序內的所有執行緒除了共享全域性變數之外還共享:

1)  程序指令

2)  大多數資料

3)  開啟的檔案(即描述符)

4)  訊號處理函式和訊號處置

5)  當前工作目錄

6)  使用者id和組id

每個執行緒有各自的:

1)  執行緒id

2)  暫存器集合,包括程式計數器和棧指標

3)  棧(用於存放區域性變數和返回位址)

4)  errno

5)  訊號掩碼

6)  優先順序

二、基本執行緒函式:建立和終止

1)#include

int pthread_create(pthread_t*tid,const pthread_attr_t *attr,void *(*func(void*)),void *arg);

建立乙個執行緒時我們最後指定的引數是由該執行緒執行的函式及其引數。該執行緒通過呼叫這個函式開始執行,然後或者顯示地終止(通過呼叫pthread_exit),或者隱式地終止(通過讓函式返回)。該函式的位址由func引數指定,該函式的唯一呼叫引數是指標arg。如果我們需要給該函式傳遞多個引數,我們就得把他們打包成乙個結構,然後把這個結構的位址作為單個引數傳遞給這個其實函式。

注意func和arg的宣告。func所指函式作為引數接受乙個通用指標(void *),又作為返回值返回乙個通用指標(void *).這使得我們可以把乙個指標(它指向我們期望的任何     內容)傳遞給執行緒,又允許執行緒返回乙個指標(它同樣指向我們期望的任何內容)

返回成功為0,失敗為非0.

2)#include

int pthread_join(pthread_t*tid,void **status);

我們可以通過這個函式等待乙個給定執行緒終止,對比與unix程序,pthread_create類似於fork,pthread_join類似於waitpid.

必須知道你個要等待執行緒的tid,如果status指標為非空,來自所等待執行緒的返回值(乙個指向某個物件的指標)將存入有status指向的位置。

3)  pthread_t pthread_self(void);

獲取自身的執行緒id。類似於程序中的getpid函式。

4)  pthread_detach函式

乙個執行緒可能是可回合的,或者是可脫離的。當乙個可匯合的執行緒終止時,它的執行緒id和退出狀態將留存待另乙個執行緒對它呼叫pthread_join。此函式把指定的執行緒轉變為脫離狀態。

三、互斥鎖

執行緒程式設計為併發程式設計或者並行程式設計,因為多個執行緒可以併發地執行且訪問相同的變數。程序程式設計中不會發生這樣的情況,但討論在程序之間的共享記憶體區時,仍然會碰到同類問題。解決這個問題的方法為互斥鎖。使用互斥鎖來保護這個共享變數。訪問該變數的前條件是持有該互斥鎖。互斥鎖是型別為pthread_mutex_t的變數。

1)#include

int pthread_mutex_lock(pthreaed_mutex_t*mptr);

int pthread_mutex_unlock(pthread_mutex_t*mptr);

如果試圖上鎖已被另外某個執行緒鎖住的乙個互斥鎖,本執行緒將被阻塞,直到該互斥鎖被解鎖為止。

如果某個互斥鎖變數時靜態分配的,我們就必須把它初始化為常值pthread_mutex_initializer.如果我們在共享記憶體區分配乙個互斥鎖,那麼必須通過呼叫pthread_mutex_init函式在執行時把它初始化。

四、條件變數

互斥鎖適合於防止同時訪問某個共享變數,但是我們需要另外某種在等待某個條件發生期間能讓我們進入睡眠的東西。

需要乙個讓主迴圈進入睡眠,直到某個執行緒通知它有事可做才醒來的方法。條件變數結合互斥鎖能夠提供這個功能。互斥鎖提供呼哧機制,條件變數提供訊號機制。條件變數時型別為pthread_cond_t的變數。

int pthread_cond_wait(pthread_cond_t *cptr,pthread_mutex_t*mptr);

int pthread_cond_signal(pthread_cond_t *cptr);

每日程式設計(二十六)

如果不存在下乙個更大的排列,則將數字重新排列成最小的排列 即公升序排列 必須原地修改,只允許使用額外常數空間。以下是一些例子,輸入位於左側列,其相應輸出位於右側列。1,2,3 1,3,2 3,2,1 1,2,3 1,1,5 1,5,1 分析 很明顯從後想前遍歷,直到找到乙個前面的數比後面的小,然後在...

二十六 遮蔽中斷

1.6410和210採用向量中斷,由硬體執行。有兩組中斷源,相應的控制暫存器也有多個 2.6410和210使能和遮蔽是分開的暫存器 3.遮蔽控制暫存器的讀寫操作從而遮蔽中斷,都是寫入全1 4.6410的 遮蔽中斷,要操作兩個暫存器,目的是將使能中斷暫存器的相關位清除 define vic0inten...

二十六 裝飾器

裝飾器 由於函式也是乙個物件,而且函式物件可以被賦值給變數,所以,通過變數也能呼叫該函式。def now print 2015 3 25 f now f 2015 3 25 函式物件有乙個 name 屬性,可以拿到函式的名字 now.name now f.name now 現在,假設我們要增強 no...