多程序與多執行緒(八)

2021-08-26 10:27:30 字數 2617 閱讀 2551

「執行緒安全」由多執行緒對共享資源的訪問引起。呵呵,前面講了共享為執行緒帶來的便利,現在,共享又引發了程式的安全問題了,真是利弊互現,不可偏頗啊。

那麼,什麼是執行緒安全呢?

一般而言,如果呼叫某個介面時需要我們自己採取同步措施來保護該介面訪問的共享資源,則這樣的介面不是執行緒安全的。

如果介面中訪問的資料都屬於私有資料,那麼這樣的介面是執行緒安全的,或者幾個介面對共享資料都是唯讀操作,那麼這樣的介面也是執行緒安全的。

如果多個介面之間有共享資料,而且有讀有寫的話,如果設計者自己採取了同步措施,呼叫者不需要考慮資料同步問題,則這樣的介面是執行緒安全的,否則不是執行緒安全的。

舉個例子說,在linux系統下,有個著名的函式「getopt」(還有個「getopt_long」),其作用是用來解析命令列引數的標準函式,但是,如果我們在多執行緒的**中使用了這兩個函式,則會帶來執行緒不安全的問題。為什麼?因為getopt使用了全域性變數。

如下**摘自pg的pgsql/src/port/getopt.c[1],我們對其做一分析:

1. 被標識為粗體帶有顏色的變數,是全域性變數,被linux系統的「getopt.h」檔案定義。

2. 假設乙個程序啟動了ta和tb兩個執行緒,這兩個執行緒都呼叫了getopt函式,不管是ta還是tb執行,它們對optind的初值要求均是0;現在,ta先執行,tb後,那麼,在tb執行時,optind的值是多少呢?很顯然,在ta執行後,optind的值不再是初值「0」,作為全域性變數,其值被儲存到tb執行之時,但這顯然不能滿足tb對optind初值的要求,這就引發了執行緒安全的問題。

3. 注意pg在getopt函式的使用上沒有執行緒安全的問題(pg在呼叫getopt時都是單獨的程序,不存在多執行緒的問題)。

4. 與getopt函式還有很多類似的系統函式,如strtok, asctime, ctime, gmtime, localtime,rand等函式,都不是執行緒安全的,在多執行緒程式設計中使用時,務必小心。

intoptopt; /* character checked for validity */

* getopt

* parse argc/argv argument vector.

intgetopt(nargc, nargv, ostr)

int nargc;

char *const * nargv;

const char *ostr;

static char *place = emsg; /* option letter processing */

char *oli; /* option letter list index */

if (optreset|| !*place)

/* option letter okay? */

if ((optopt= (int) *place++) == (int) ':' ||

!(oli = strchr(ostr,optopt)))

* if the user didn't specify '-' as an option, assume it means -1.

if (optopt== (int) '-')

return -1;

if (!*place)

++optind; //全域性變數的值發生改變

if (opterr&& *ostr != ':')

(void) fprintf(stderr,

"illegal option -- %c\n",optopt);

return badch;

if (*++oli != ':')

{ /* don't need argument */

optarg = null;

if (!*place)

++optind; //全域性變數的值發生改變

else

{ /* need an argument */

if (*place) /* no white space */

optarg = place;

else if (nargc <= ++optind) //全域性變數的值發生改變

{ /* no arg */

place = emsg;

if (*ostr == ':')

return badarg;

if (opterr)

(void) fprintf(stderr,

"option requires an argument -- %c\n",

optopt);

return badch;

else

/* white space */

optarg = nargv[optind];

place = emsg;

+

多執行緒與多程序

程序 程序是程式的一次執行,在傳統的計算機中,程序既是基本的分配單元,也是基本的執行單元。執行緒 執行緒是可執行的實體單元,它是處理機排程的基本單位。由於執行緒在同一位址空間,因此建立和撤銷執行緒的開銷小,執行緒間的通訊效率高,切換迅速。在多處理機系統中,對程序的個數有所限制,但對執行緒的個數不存在...

多執行緒與多程序

魚還是熊掌 多程序多執行緒的選擇 關於多程序和多執行緒,教科書上最經典的一句話是 程序是資源分配的最小單位,執行緒是cpu排程的最小單位 這句話應付考試基本上夠了,但如果在工作中遇到類似的選擇問題,那就沒有這麼簡單了,選的不好,會讓你深受其害。經常在網路上看到有的xdjm問 多程序好還是多執行緒好?...

多程序與多執行緒

import threading建立乙個執行緒,指向的函式,不接收引數的情況 t threading.thread target 函式名 建立乙個執行緒,指向的函式,收引數的情況 t threading.thread target 函式名,args 實參1,執行緒物件名.start 生命週期 我們的...