第 11 章 多線程技術(shù)_第1頁
第 11 章 多線程技術(shù)_第2頁
第 11 章 多線程技術(shù)_第3頁
第 11 章 多線程技術(shù)_第4頁
第 11 章 多線程技術(shù)_第5頁
已閱讀5頁,還剩53頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

第11章多線程技術(shù)內(nèi)容提要線程概述創(chuàng)建新進(jìn)程線程控制線程取消線程同步多線程環(huán)境下的信號處理非線程安全函數(shù)的改造11.1線程概述線程概述

線程如同進(jìn)程是系統(tǒng)可獨(dú)立調(diào)度的最小執(zhí)行單元,它們僅在資源的使用方式上有所不同,進(jìn)程間的用戶地址空間彼此獨(dú)立,然而,線程卻共享創(chuàng)建者進(jìn)程的用戶地址空間等資源。引入線程的目的是為了減少對資源的消耗。創(chuàng)建新進(jìn)程時,用戶可根據(jù)需求定制進(jìn)程,,進(jìn)程和線程為兩種最常見的新進(jìn)程定制類型。進(jìn)程與線程的關(guān)系棧(stack)文件描述符表?xiàng)?stack)代碼段(text)數(shù)據(jù)段(data)堆(heap)文件描述符表代碼段(text)數(shù)據(jù)段(data)堆(heap)線程線程棧(stack)進(jìn)程多線程進(jìn)程Linux線程的實(shí)現(xiàn)

由于線程誕生的時間較晚,早期的操作系統(tǒng)內(nèi)核并不支持線程。1.用戶線程對不支持內(nèi)核線程的操作系統(tǒng),通過編程技巧,在一個進(jìn)程中,可模擬出多條被稱為用戶線程的執(zhí)行路徑,但用戶線程存在很多不足。2.內(nèi)核線程內(nèi)核線程通過修改內(nèi)核代碼實(shí)現(xiàn),目前,現(xiàn)代操作系統(tǒng)均支持內(nèi)核線程。Linux線程的實(shí)現(xiàn)(續(xù))1.LinuxThreads

LinuxThreads為POSIX線程庫的早期版本,自glibc2.4起不再使用,因受當(dāng)時內(nèi)核對線程支持不足的影響,LinuxThreads僅實(shí)現(xiàn)了POSIX線程的部分標(biāo)準(zhǔn)。2.NPTL

NPTL(NativePOSIXThreadsLibrary)屬于POSIX線程庫的現(xiàn)代版本,最早出現(xiàn)于glibc2.3.2,需內(nèi)核2.6以上版本的支持。相較于LinuxThreads,NPTL更符合POSIX標(biāo)準(zhǔn),在創(chuàng)建大量線程的情況下,具有更高的性能。應(yīng)用編程接口分類API功能描述創(chuàng)建新進(jìn)程clone創(chuàng)建新的進(jìn)程線程屬性pthread_attr_init初始化線程屬性對象pthread_attr_destroy注銷線程屬性對象pthread_attr_getstack獲取線程棧的地址和大小pthread_attr_setstack設(shè)置線程棧的地址和大小pthread_attr_getdetachstate獲取線程的分離屬性pthread_attr_setdetachstate設(shè)置線程的分離屬性pthread_create創(chuàng)建線程pthread_join等待線程運(yùn)行結(jié)束pthread_exit結(jié)束線程線程取消pthread_cancel向線程發(fā)送取消請求pthread_setcancelstate設(shè)置線程取消的狀態(tài)pthread_setcanceltype設(shè)置線程取消的類型pthread_testcancel測試線程的取消請求是否到達(dá)pthread_cleanup_push注冊線程清理函數(shù)應(yīng)用編程接口線程同步互斥鎖pthread_mutex_init初始化互斥鎖pthread_mutex_destroy注銷互斥鎖pthread_mutex_lock申請獲得互斥鎖pthread_mutex_unlock釋放互斥鎖條件變量pthread_cond_init條件變量的初始化pthread_cond_wait等待條件變量pthread_cond_signal喚醒等待條件變量的線程pthread_cond_destroy注銷條件變量線程的信號處理pthread_kill向線程發(fā)送信號pthread_sigqueue向線程發(fā)送實(shí)時信號pthread_sigmask設(shè)置線程的信號掩碼非線程安全函數(shù)的安全化改造pthread_key_create創(chuàng)建線程持有數(shù)據(jù)關(guān)聯(lián)的鍵值pthread_key_delete刪除線程持有數(shù)據(jù)關(guān)聯(lián)的鍵值pthread_setspecific設(shè)置鍵關(guān)聯(lián)的線程持有數(shù)據(jù)pthread_getspecific獲取鍵關(guān)聯(lián)的線程持有數(shù)據(jù)11.2創(chuàng)建新進(jìn)程創(chuàng)建新進(jìn)程

自Linux內(nèi)核2.0起,內(nèi)核引入了clone系統(tǒng)調(diào)用,實(shí)現(xiàn)了對內(nèi)核線程的初步支持,使用該系統(tǒng)調(diào)用可定制新的進(jìn)程,其功能隨著Linux的發(fā)展不斷完善,glibc中的線程庫正是基于該系統(tǒng)調(diào)用構(gòu)建。創(chuàng)建子進(jìn)程頭文件

#define_GNU_SOURCE #include<sched.h>函數(shù)原型

int

clone(int(*fn)(void*),void*child_stack,intflags,void*arg…/*pid_t*ptid,void*newtls,pid_t*ctid*/);功能 創(chuàng)建新的進(jìn)程。參數(shù)

fn:函數(shù)地址。

child_stack:棧地址。

flags:共享創(chuàng)建者進(jìn)程的方式。

arg:指向傳遞的參數(shù)。返回值 成功返回線程的PID,失敗返回-1。11.3線程控制線程屬性

線程擁有諸多屬性,例如,棧和信號掩碼等,在創(chuàng)建線程前,根據(jù)特定的應(yīng)用場景,應(yīng)對其中部分屬性進(jìn)行設(shè)置。1.初始化/注銷線程屬性對象。2.獲取/設(shè)置線程棧。3.獲取/設(shè)置線程的分離屬性。初始化/注銷線程屬性對象頭文件

#include<pthread.h>函數(shù)原型 int

pthread_attr_init(pthread_attr_t*attr);

int

pthread_attr_destroy(pthread_attr_t*attr);功能 初始化/注銷線程屬性對象。參數(shù)

attr:線程屬性對象。返回值 成功返回0,失敗返回-1非0設(shè)置線程棧頭文件

#include<pthread.h>函數(shù)原型

int

pthread_attr_getstack(pthread_attr_t*attr,void**addr,size_t*size);

int

pthread_attr_setstack(pthread_attr_t*attr,void*addr,size_tsize);功能 獲取/設(shè)置線程棧。參數(shù)

attr:線程屬性對象。

addr:線程棧地址。

size:線程棧大小。返回值 成功返回0,失敗返回非0。設(shè)置線程的分離屬性頭文件

#include<pthread.h>函數(shù)原型

int

pthread_attr_getdetachstate(pthread_attr_t*attr,int*state);

int

pthread_attr_setdetachstate(pthread_attr_t*attr,intstate);功能 獲取/設(shè)置線程的分離屬性。參數(shù)

attr:線程的屬性對象。

state:狀態(tài)標(biāo)志。返回值 成功返回0,失敗返回非0。創(chuàng)建線程頭文件

#include<pthread.h>函數(shù)原型

int

pthread_create(pthread_t*tid,pthread_attr_t*attr,void*(*start)(void*),void*args);功能 創(chuàng)建線程。參數(shù)

tid:線程ID。

attr:線程的屬性。

start:線程執(zhí)行的開始地址。

args:傳遞的參數(shù)。返回值

pthread_create函數(shù)成功返回0,失敗返回錯誤代碼。等待線程結(jié)束頭文件

#include<pthread.h>函數(shù)原型

int

pthread_join(pthread_t

tid,void**status)功能 等待線程結(jié)束。參數(shù)

tid:線程ID。

status:線程的返回狀態(tài)。返回值 成功返回0,失敗返回錯誤代碼。結(jié)束線程頭文件

#include<pthread.h>函數(shù)原型

voidpthread_exit(void*retval);功能 結(jié)束線程。參數(shù)

retval:返回狀態(tài)。返回值 無返回。11.4線程取消內(nèi)容提要線程取消概述創(chuàng)建線程取消點(diǎn)線程的取消狀態(tài)和類型清理函數(shù)向線程發(fā)送取消請求線程取消概述

對于某些應(yīng)用,有時需要取消正在運(yùn)行的線程,為此,在線程的執(zhí)行路徑上引入取消點(diǎn),并設(shè)置響應(yīng)的處理函數(shù),當(dāng)需要取消線程運(yùn)行時,可線程發(fā)送取消請求,當(dāng)線運(yùn)行至取消點(diǎn)時,將檢查是否由取消請求到達(dá),當(dāng)有取消請求到達(dá)時,執(zhí)行響應(yīng)的處理函數(shù)并退出運(yùn)行。測試取消請求頭文件

#include<pthread.h>函數(shù)原型

voidpthread_testcancel(void);功能 測試線程的取消請求是否到達(dá)。參數(shù) 無參數(shù)。返回值 若取消請求已到達(dá),結(jié)束線程,否則,立即返回。線程的取消狀態(tài)和類型

線程的取消有啟用和禁用兩種狀態(tài),在禁用狀態(tài)下,線程收到的取消請求將被阻塞直至狀態(tài)被啟用;在啟用狀態(tài)下,線程會對收到的取消請求進(jìn)行處理,具體方式取決于線程取消的類型設(shè)置線程的取消狀態(tài)頭文件

#include<pthread.h>函數(shù)原型

int

pthread_setcancelstate(intstate,int*oldstate);功能 設(shè)置線程的取消狀態(tài)。參數(shù)

state:取消狀態(tài)。

oldstate:原有狀態(tài)地址。返回值 成功返回0,失敗返回錯誤代碼。設(shè)置線程取消的處理類型頭文件

#include<pthread.h>函數(shù)原型

int

pthread_setcanceltype(inttype,int*oldtype);功能 設(shè)置線程取消的處理類型參數(shù)

type:處理類型。

oldtype:原處理類型地址。返回值 成功,返回0,失敗,返回錯誤代碼。線程清理函數(shù)

清理函數(shù)是線程取消時執(zhí)行的函數(shù),執(zhí)行線程結(jié)束前的清理工作,以便線程安全退出。例如,釋放互斥鎖,以免死鎖的發(fā)生。

清理函數(shù)以棧的形式存放,通常,收到取消請求的線程在到達(dá)下一個取消點(diǎn)時,清理函數(shù)以后進(jìn)先出的方式執(zhí)行。設(shè)置清理函數(shù)pthread_cleanup_push/pthread_cleanup_pop函數(shù)頭文件

#include<pthread.h>函數(shù)原型

voidpthread_cleanup_push(void(*routine)(void*),void*arg); voidpthread_cleanup_pop(intexecute);功能 注冊/注銷線程清理函數(shù)。參數(shù)

routine:線程清理函數(shù)地址。

arg:傳遞的參數(shù)。

execute:執(zhí)行標(biāo)志。返回值 無返回值。發(fā)送取消請求pthread_cancel函數(shù)頭文件

#include<pthread.h>函數(shù)原型

int

pthread_cancel(pthread_tthread);功能 向線程發(fā)送取消請求。參數(shù)

thread:線程ID。返回值 成功返回0,失敗返回錯誤代碼。11.5線程同步互斥鎖

互斥鎖是一種管理臨界區(qū)訪問的同步控制機(jī)制,確保同一時間段僅有一個線程訪問臨界區(qū)、線程訪問臨界區(qū)前,需申請互斥鎖,只有獲得互斥鎖的線程允許進(jìn)入臨界區(qū),未獲得互斥鎖的線程進(jìn)入等待狀態(tài),直至獲得釋放的互斥鎖?;コ怄i的初始化頭文件

#include<pthread.h>函數(shù)原型

pthread_mutex_t

mutex=PTHREAD_MUTEX_INITIALIZER;

int

pthread_mutex_init(pthread_mutex_t*mp,pthread_mutexattr_t*mattr)

int

pthread_mutex_destroy(pthread_mutex_t*mp)功能 初始化/注銷互斥鎖。參數(shù)

mp:互斥鎖。

mattr:互斥鎖屬性。返回值 成功,返回0,失敗,返回錯誤代碼。申請/釋放互斥鎖pthread_mutex_lock/pthread_mutex_unlock函數(shù)頭文件

#include<pthread.h>函數(shù)原型

int

pthread_mutex_lock(pthread_mutex_t*mp)

int

pthread_mutex_unlock(pthread_mutex_t*mp)功能 申請/釋放互斥鎖。參數(shù)

mp:互斥鎖。返回值 成功返回0,失敗返回錯誤代碼。條件變量

條件變量是一種線程間基于條件的協(xié)調(diào)機(jī)制。,以條件變量的形式表示某種條件。當(dāng)線程訪問的條件不成立,線程將在條件變量上等待,直至條件得到滿足。條件變量的相關(guān)函數(shù)屬于非信號安全函數(shù)。初始化條件變量(1)pthread_cond_t

cond=PTHREAD_COND_INITIALIZER;//靜態(tài)條件變量初始化(2)pthread_cond_init/pthread_cond_destroy函數(shù)頭文件

#include<pthread.h>函數(shù)原型

int

pthread_cond_init(pthread_cond_t*cv,pthread_condattr_t*cattr)

int

pthread_cond_destroy(pthread_cond_t*cv)功能 初始化/注銷條件變量。參數(shù)

cv:條件變量。

cattr:條件變量屬性。返回值 成功返回0,失敗返回錯誤代碼。等待/釋放條件變量thread_cond_wait/pthread_cond_signal函數(shù)頭文件

#include<pthread.h>函數(shù)原型

int

pthread_cond_wait(pthread_cond_t*cv,pthread_mutex_t*mutex)

int

pthread_cond_signal(pthread_cond_t*cv)

int

pthread_cond_broadcast(pthread_cond_t*cv)功能 等待/釋放條件變量參數(shù)

cv:條件變量。

mutex:互斥鎖。返回值 成功返回0,失敗返回錯誤代碼。11.6多線程環(huán)境下的信號處理內(nèi)容提要多線程環(huán)境下的信號線程的信號掩碼多線程環(huán)境下的信號處理多線程環(huán)境下的信號

線程共享所屬進(jìn)程的信號處理方式,信號可發(fā)送至進(jìn)程或進(jìn)程中的某個線程。對于面向進(jìn)程的信號,信號被進(jìn)程中所有線程共享,進(jìn)程中任意線程可對信號進(jìn)行處理,具體的執(zhí)行線程取決于調(diào)度時機(jī);對于面向線程的信號,僅由目標(biāo)線程處理。線程的信號掩碼

線程有獨(dú)立的信號掩碼,線程的信號掩碼繼承自創(chuàng)建者進(jìn)程。信號掩碼為若干信號構(gòu)成的集合,用于定義阻塞的信號。設(shè)置線程的信號掩碼1.pthread_sigmask函數(shù)頭文件

#include<signal.h>函數(shù)原型

int

pthread_sigmask(inthow,constsigset_t*set,sigset_t*oldset);功能 設(shè)置線程的信號掩碼參數(shù)

how:操作方式。

set:新信號掩碼地址。

oldset:原信號掩碼地址。向線程發(fā)送信號pthread_kill/pthread_sigqueue函數(shù)頭文件

#include<signal.h>函數(shù)原型

int

pthread_kill(pthread_t

tid,int

sig);

int

pthread_sigqueue(pthread_t

tid,int

sig,constunionsigvalvalue);功能 向線程發(fā)送信號。參數(shù)

tid:線程ID。

Sig:信號編號。

Value:傳遞的數(shù)據(jù)。返回值 成功返回0,失敗返回錯誤代碼。多線程環(huán)境下的信號處理

由于線程與信號的異步特性,為簡化多線程環(huán)境下的信號處理,僅指定一個線程以同步方式處理到達(dá)的信號。將其他信號設(shè)置為阻塞狀態(tài)。該處理方式可避免線程與信號處理程序間的資源競爭,從而降低程序設(shè)計(jì)的復(fù)雜性,提高程序的可讀性和可靠性。11.7非線程安全函數(shù)的改造內(nèi)容提要線程安全函數(shù)非線程安全函數(shù)非線程安全函數(shù)的改造線程的設(shè)計(jì)原則線程安全函數(shù)

當(dāng)函數(shù)被多個線程同時調(diào)用時,若總能保證程序運(yùn)行的正確性,則函數(shù)稱為線程安全函數(shù)。若函數(shù)及其引用的子函數(shù)未使用全局變量或靜態(tài)變量,則函數(shù)稱為可重入函數(shù)??芍厝牒瘮?shù)一定是信號安全函數(shù),反之,未必成立。對于函數(shù)中引用的全局變量或靜態(tài)變量,若使用互斥鎖進(jìn)行了控制,則也可使函數(shù)稱為信號安全的,非線程安全函數(shù)

當(dāng)函數(shù)被多個線程同時調(diào)用時,若不能始終保持其正確性,則函數(shù)稱為非信號安全函數(shù)。

glibc中的某些函數(shù)由于編寫時間較早,誕生于線程出現(xiàn)之前,并未考慮多線程環(huán)境,有些函數(shù)的參數(shù)或返回值使用了全局變量或靜態(tài)變量,因此,它們?yōu)榉蔷€程安全函數(shù)。例如,ctime和readdir函數(shù)等。非線程安全函數(shù)strerror非線程安全函數(shù)的改造

非線程安全函數(shù)的安全化改造就是指在功能和接口不變的前提下,將其轉(zhuǎn)變?yōu)榫€程安全的函數(shù),具體做法是將函數(shù)中的全局變量替換為線程持有變量,使每個線程擁有一份拷貝,以防止競爭現(xiàn)象的發(fā)生。根據(jù)轉(zhuǎn)換方法的不同,可進(jìn)一步劃分為:1.線程持有數(shù)據(jù)2.線程局部存儲

線程持有數(shù)據(jù)

對于非線程安全函數(shù)中的全局/靜態(tài)變量,為每個線程創(chuàng)建一份稱為線程持有數(shù)據(jù)的拷貝,以避免資源競爭的發(fā)生。

POSIX提供了一系列接口函數(shù),為每個全局/靜態(tài)變量創(chuàng)建一個以鍵值關(guān)聯(lián)的數(shù)組,數(shù)組以線程ID為索引存放線程持有的數(shù)據(jù)。初始化實(shí)例(1)pthread_once函數(shù)頭文件

#include<pthread.h>函數(shù)原型

int

pthread_once(pthread_once_t*once_control,void(*init_routine)(void));功能 僅初始化一次。參數(shù)

once_control:一次性控制變量。

init_routine:初始化函數(shù)地址。返回值 返回0。創(chuàng)建/刪除線程持有數(shù)據(jù)關(guān)聯(lián)的鍵值(2)pthread_key_create/pthread_key_delete函數(shù)頭文件

#include<pthread.h>函數(shù)原型

int

pthread_key_create(pthread_key_t*key,void(*destr_function)(void*));

int

pthread_key_delete(pthread_key_tkey);功能 創(chuàng)建/刪除鍵值。參數(shù)

Key:鍵值。

destr_function:析構(gòu)函數(shù)。返回值 成功,返回0,失敗,返回非0。獲取/設(shè)置鍵值關(guān)聯(lián)的線程持有數(shù)據(jù)(3)pthread_getspecific/pthread_setspecific函數(shù)頭文件

#include<pthread.h>函數(shù)原型

void*pthread_getspecific(pthread_key_tkey);

int

pthread_setspecific(pthread_key_tkey,constvoid*pointer);功能 獲取/設(shè)置鍵值關(guān)聯(lián)的線程持有數(shù)據(jù)。參數(shù)

Key:鍵值。

pointer:線程持有數(shù)據(jù)地址。返回值

pthread_setspecific成功返回0,失敗返回非0?;诰€程持有數(shù)據(jù)的安全化改造staticpthread_once_tonce=PTHREAD_ONCE_INIT;staticpthread_key_t

strerrorKey;voidbuffer_destroy(void*buf){

free(buf);}voidbuffer_key_alloc(void){

ints; s=pthread_key_create(&strerrorKey,buffer_destroy); if(s!=0) err(1,"pthread_key_createfailed\n");}char*strerror(int

nerr){

ints; char*buf; s=pthread_once(&once,buffer_key_alloc); if(s!=0) err(1,"pthread_oncefailed\

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論