国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 操作系統(tǒng) > 正文

線(xiàn)程之線(xiàn)程的創(chuàng)建

2024-06-28 13:28:25
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友
線(xiàn)程之線(xiàn)程的創(chuàng)建

在傳統(tǒng)的UNIX進(jìn)程模型中,每個(gè)進(jìn)程只有一個(gè)控制線(xiàn)程。從概念上講,這與基于線(xiàn)程的模型中只包含一個(gè)線(xiàn)程是相同的。在POSIX線(xiàn)程(pthread)的情況下,程序開(kāi)始運(yùn)行時(shí),它也是以單進(jìn)程中的單個(gè)控制線(xiàn)程啟動(dòng)的,在創(chuàng)建多個(gè)控制線(xiàn)程以前,程序的行為與傳統(tǒng)的進(jìn)程并沒(méi)有什么區(qū)別。新增的線(xiàn)程可以通過(guò)調(diào)用pthread_create函數(shù)創(chuàng)建

#include <pthread.h>int pthread_create(pthread_t *restrict tidp,                  const pthread_attr_t *restrict attr,                  void *(*start_rtn)(void *), void *restrict arg);返回值:若成功則返回0,否則返回錯(cuò)誤編號(hào)

當(dāng)pthread_create成功返回時(shí),由tidp指向的內(nèi)存單元被設(shè)置為新創(chuàng)建的線(xiàn)程的線(xiàn)程IDattr參數(shù)用于定制各種不同的線(xiàn)程屬性。線(xiàn)程屬性在以后介紹,眼下暫時(shí)把它設(shè)置為NULL,創(chuàng)建默認(rèn)屬性的線(xiàn)程。

新創(chuàng)建的線(xiàn)程從start_rtn函數(shù)的地址開(kāi)始運(yùn)行該函數(shù)只有一個(gè)無(wú)類(lèi)型指針參數(shù)arg,如果需要向start_rtn函數(shù)傳遞的參數(shù)不止一個(gè),那么需要把這些參數(shù)放到一個(gè)結(jié)構(gòu)中,然后把這個(gè)結(jié)構(gòu)的地址作為arg參數(shù)傳入

線(xiàn)程創(chuàng)建時(shí)并不能保證哪個(gè)線(xiàn)程會(huì)先運(yùn)行:是新創(chuàng)建的線(xiàn)程還是調(diào)用線(xiàn)程。新創(chuàng)建的線(xiàn)程可以訪問(wèn)進(jìn)程的地址空間,并且繼承調(diào)用線(xiàn)程的浮點(diǎn)環(huán)境和信號(hào)屏蔽字,但是該線(xiàn)程的未決信號(hào)集被清除。

注意pthread函數(shù)在調(diào)用失敗時(shí)通常會(huì)返回錯(cuò)誤碼,它們并不像其他的POSIX函數(shù)一樣設(shè)置errno。每個(gè)線(xiàn)程都提供errno的副本,這只是為了與使用errno的現(xiàn)有函數(shù)兼容。在線(xiàn)程中,從函數(shù)中返回錯(cuò)誤碼更為清晰整潔,不需要依賴(lài)那些隨著函數(shù)執(zhí)行不斷變化的全局狀態(tài),因而可以把錯(cuò)誤的范圍限制在引起出錯(cuò)的函數(shù)中。

實(shí)例

雖然沒(méi)有可移植的方法打印線(xiàn)程ID,但是可以寫(xiě)一個(gè)小的測(cè)試程序來(lái)完成這個(gè)任務(wù),以便更深入地了解線(xiàn)程是如何工作的。程序清單11-1中創(chuàng)建了一個(gè)線(xiàn)程并且打印進(jìn)程ID、新線(xiàn)程的線(xiàn)程ID以及初始線(xiàn)程的線(xiàn)程ID。

程序清單11-1 打印線(xiàn)程ID

#include "apue.h"#include <pthread.h>pthread_t ntid;void PRintids(const char *s){    pid_t        pid;    pthread_t    tid;    pid = getpid();    tid = pthread_self();    printf("%s pid %u tid %u (0x%x) /n", s, (unsigned int)pid,        (unsigned int)tid, (unsigned int)tid);}void *thr_fn(void *arg){    printids("new thread : ");    return((void *)0);}intmain(void){    int    err;            err = pthread_create(&ntid, NULL, thr_fn, NULL);    if(err != 0)        err_quit("can't create thread: %s/n", strerror(err));    printids("main thread: ");    sleep(1);    exit(0);}

編譯上面程序過(guò)程中遇到了undefined reference to ‘pthread_create’的問(wèn)題:

未命名

首先,檢查了函數(shù)名,沒(méi)有寫(xiě)錯(cuò);然后檢查了頭文件<pthread.h>,也包含了。這種摸不著頭腦的問(wèn)題總是讓人很糾結(jié)的......最終在網(wǎng)上找到了出現(xiàn)該問(wèn)題的原因及其解決方案,參考自:http://blog.csdn.net/llqkk/article/details/2854558

問(wèn)題原因: pthread 庫(kù)不是 linux 系統(tǒng)默認(rèn)的庫(kù),連接時(shí)需要使用靜態(tài)庫(kù) libpthread.a,所以在使用pthread_create()創(chuàng)建線(xiàn)程,以及調(diào)用 pthread_atfork()函數(shù)建立fork處理程序時(shí),需要鏈接該庫(kù)。 解決方案: 在編譯中要加 -lpthread參數(shù)

未命名

問(wèn)題解決了就OK了嗎?當(dāng)然不行,由此問(wèn)題恰好暴露了之前學(xué)過(guò)的一些知識(shí)其實(shí)并沒(méi)有真正吃透,學(xué)的時(shí)候理解,遇到問(wèn)題的時(shí)候卻想不起來(lái)。其實(shí)上面出現(xiàn)的這個(gè)問(wèn)題牽涉到了之前學(xué)過(guò)的如下兩個(gè)知識(shí)點(diǎn):

(1)軟件開(kāi)發(fā)工具GCC http://www.CUOXin.com/nufangrensheng/p/3426405.html。注意其中的GCC鏈接選項(xiàng)部分。

(2)UNIX標(biāo)準(zhǔn)化及實(shí)現(xiàn)之POSIX標(biāo)準(zhǔn)可選頭文件 http://www.CUOXin.com/nufangrensheng/p/3496116.html。從中可以看到pthread.h是POSIX標(biāo)準(zhǔn)的可選頭文件,也就是說(shuō)pthread庫(kù)不是Linux系統(tǒng)默認(rèn)的庫(kù),鏈接時(shí)需要使用靜態(tài)庫(kù)libpthread.a。

更多關(guān)于undefined reference to...的問(wèn)題可參考:http://ticktick.blog.51cto.com/823160/431329

現(xiàn)在我們言歸正傳,從程序清單11-1運(yùn)行結(jié)果來(lái)看,兩個(gè)線(xiàn)程的進(jìn)程ID相同,但線(xiàn)程ID不同。不過(guò)這不是絕對(duì)的,依賴(lài)于具體的實(shí)現(xiàn)。

這個(gè)實(shí)例有兩個(gè)需要注意的地方:

(1)需要處理主線(xiàn)程和新線(xiàn)程之間的競(jìng)爭(zhēng)。首先是主線(xiàn)程需要休眠,如果主線(xiàn)程不休眠,它就可能退出,這樣在新線(xiàn)程有機(jī)會(huì)運(yùn)行之前整個(gè)進(jìn)程可能就已經(jīng)終止了。這種行為特征依賴(lài)于操作系統(tǒng)中的線(xiàn)程實(shí)現(xiàn)和調(diào)度算法。

(2)新線(xiàn)程是通過(guò)調(diào)用pthread_self函數(shù)獲取自己的線(xiàn)程ID,而不是從共享內(nèi)存中讀出或者從線(xiàn)程的啟動(dòng)例程中以參數(shù)的形式接收到。回憶pthread_create函數(shù),它會(huì)通過(guò)第一個(gè)參數(shù)(tidp)返回新建線(xiàn)程的線(xiàn)程ID。在本例中,主線(xiàn)程把新線(xiàn)程ID存放在ntid中,但是新建的線(xiàn)程并不能安全地使用它,如果新線(xiàn)程在主線(xiàn)程調(diào)用pthread_create返回之前就運(yùn)行了,那么新線(xiàn)程看到的是未經(jīng)初始化的ntid的內(nèi)容,這個(gè)內(nèi)容并不是正確的線(xiàn)程ID。

本篇博文內(nèi)容摘自《UNIX環(huán)境高級(jí)編程》(第二版),僅作個(gè)人學(xué)習(xí)記錄所用。關(guān)于本書(shū)可參考:http://www.apuebook.com/


發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 绥中县| 兴国县| 连江县| 阳朔县| 南京市| 丘北县| 佛冈县| 永兴县| 富源县| 四子王旗| 桐庐县| 随州市| 江孜县| 贺兰县| 丁青县| 许昌市| 柳林县| 手游| 马鞍山市| 沙河市| 方山县| 南阳市| 西华县| 曲靖市| 汽车| 清流县| 蒙自县| 哈密市| 个旧市| 蒙山县| 揭西县| 衢州市| 盐边县| 江口县| 吉水县| 东乌| 宣化县| 吉林省| 额济纳旗| 长汀县| 定襄县|