婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > Linux下的多線程編程和fork()函數(shù)詳解

Linux下的多線程編程和fork()函數(shù)詳解

熱門標簽:百度地圖地圖標注客服多少 iphone地圖標注我的店鋪 哪種品牌的400電話申請 百度ai電銷機器人排名 ai智能外呼系統(tǒng)是什么 適用的400電話辦理 廣東電話機器人開戶 成都米蘭申請 旅游路書地圖標注

 一、fork()函數(shù)

在操作系統(tǒng)的基本概念中進程是程序的一次執(zhí)行,且是擁有資源的最小單位和調度單位(在引入線程的操作系統(tǒng)中,線程是最小的調度單位)。在Linux系統(tǒng)中 創(chuàng)建進程有兩種方式:一是由操作系統(tǒng)創(chuàng)建,二是由父進程創(chuàng)建進程(通常為子進程)。系統(tǒng)調用函數(shù)fork()是創(chuàng)建一個新進程的唯一方式,當然 vfork()也可以創(chuàng)建進程,但是實際上其還是調用了fork()函數(shù)。fork()函數(shù)是Linux系統(tǒng)中一個比較特殊的函數(shù),其一次調用會有兩個返 回值,下面是fork()函數(shù)的聲明:

 

#include unistd.h>

// On success, The PID of the process is returned in the parent,
 and 0 is returned in the child. On failure,
// -1 is returned in the parent, no child process is created, 
and errno is set appropriately.
pid_t fork (void);

當程序調用fork()函數(shù)并返回成功之后,程序就將變成兩個進程,調用fork()者為父進程,后來生成者為子進程。這兩個進程將執(zhí)行相同的程序文本, 但卻各自擁有不同的棧段、數(shù)據(jù)段以及堆棧拷貝。子進程的棧、數(shù)據(jù)以及棧段開始時是父進程內存相應各部分的完全拷貝,因此它們互不影響。從性能方面考慮,父 進程到子進程的數(shù)據(jù)拷貝并不是創(chuàng)建時就拷貝了的,而是采用了寫時拷貝(copy-on -write)技術來處理。調用fork()之后,父進程與子進程的執(zhí)行順序是我們無法確定的(即調度進程使用CPU),意識到這一點極為重要,因為在一些設計不好的程序中會導致資源競爭,從而出現(xiàn)不可預知的問題。下圖為寫時拷貝技術處理前后的示意圖:

在Linux系統(tǒng)中,常常存在許多對文件的操作,fork()的執(zhí)行將會對文件操作帶來一些小麻煩。由于子進程會將父進程的大多數(shù)數(shù)據(jù)拷貝一份,這樣在文 件操作中就意味著子進程會獲得父進程所有文件描述符的副本,這些副本的創(chuàng)建方式類似于dup()函數(shù)調用,因此父、子進程中對應的文件描述符均指向相同的 打開的文件句柄,而且打開的文件句柄包含著當前文件的偏移量以及文件狀態(tài)標志,所以在父子進程中處理文件時要考慮這種情況,以避免文件內容出現(xiàn)混亂或者別 的問題。下圖為執(zhí)行fork()調用后文件描述符的相關處理及其變化:

二、線程

與進程類似,線程(thread)是允許應用程序并發(fā)執(zhí)行多個任務的一種機制。一個進程中可以包含多個線程,同一個程序中的所有線程均會獨立執(zhí)行,且共享 同一份全局內存區(qū)域,其中包括初始化數(shù)據(jù)段(initialized data),未初始化數(shù)據(jù)段(uninitialized data),以及堆內存段(heap segment)。在多處理器環(huán)境下,多個線程可以同時執(zhí)行,如果線程數(shù)超過了CPU的個數(shù),那么每個線程的執(zhí)行順序將是無法確定的,因此對于一些全局共 享數(shù)據(jù)據(jù)需要使用同步機制來確保其的正確性。

在系統(tǒng)中,線程也是稀缺資源,一個進程能同時創(chuàng)建多少個線程這取決于地址空間的大小和內核參數(shù),一臺機器可以同時并發(fā)運行多少個線程也受限于CPU的數(shù) 目。在進行程序設計時,我們應該精心規(guī)劃線程的個數(shù),特別是根據(jù)機器CPU的數(shù)目來設置工作線程的數(shù)目,并為關鍵任務保留足夠的計算資源。如果你設計的程 序在背地里啟動了額外的線程來執(zhí)行任務,那這也屬于資源規(guī)劃漏算的情況,從而影響關鍵任務的執(zhí)行,最終導致無法達到預期的性能。很多程序中都存在全局對 象,這些全局對象的初始化工作都是在進入main()函數(shù)之前進行的,為了能保證全局對象的安全初始化(按順序的),因此在程序進入main()函數(shù)之前 應該避免線程的創(chuàng)建,從而杜絕未知錯誤的發(fā)生。

三、fork()與多線程

在程序中fork()與多線程的協(xié)作性很差,這是POSIX系列操作系統(tǒng)的歷史包袱。因為長期以來程序都是單線程的,fork()運轉正常。當20世紀90年代初期引入線程之后,fork()的適用范圍就大為縮小了。

在多線程執(zhí)行的情況下調用fork()函數(shù),僅會將發(fā)起調用的線程復制到子進程中。(子進程中該線程的ID與父進程中發(fā)起fork()調用的線程ID是一樣的,因此,線程ID相同的情況有時我們需要做特殊的處理。)也就是說不能同時創(chuàng)建出于父進程一樣多線程的子進程。其他線程均在子進程中立即停止并消失,并且不會為這些線程調用清理函數(shù)以及針對線程局部存儲變量的析構函數(shù)。這將導致下列一些問題:

1. 雖然只將發(fā)起fork()調用的線程復制到子進程中,但全局變量的狀態(tài)以及所有的pthreads對象(如互斥量、條件變量等)都會在子進程中得以保留, 這就造成一個危險的局面。例如:一個線程在fork()被調用前鎖定了某個互斥量,且對某個全局變量的更新也做到了一半,此時fork()被調用,所有數(shù) 據(jù)及狀態(tài)被拷貝到子進程中,那么子進程中對該互斥量就無法解鎖(因為其并非該互斥量的屬主),如果再試圖鎖定該互斥量就會導致死鎖,這是多線程編程中最不 愿意看到的情況。同時,全局變量的狀態(tài)也可能處于不一致的狀態(tài),因為對其更新的操作只做到了一半對應的線程就消失了。fork()函數(shù)被調用之后,子進程 就相當于處于signal handler之中,此時就不能調用線程安全的函數(shù)(用鎖機制實現(xiàn)安全的函數(shù)),除非函數(shù)是可重入的,而只能調用異步信號安全(async- signal-safe)的函數(shù)。fork()之后,子進程不能調用:

  1. malloc(3)。因為malloc()在訪問全局狀態(tài)時會加鎖。
  2. 任何可能分配或釋放內存的函數(shù),包括new、map::insert()、snprintf() ……
  3. 任何pthreads函數(shù)。你不能用pthread_cond_signal()去通知父進程,只能通過讀寫pipe(2)來同步。
  4. printf()系列函數(shù),因為其他線程可能恰好持有stdout/stderr的鎖。
  5. 除了man 7 signal中明確列出的“signal安全”函數(shù)之外的任何函數(shù)。

2. 因為并未執(zhí)行清理函數(shù)和針對線程局部存儲數(shù)據(jù)的析構函數(shù),所以多線程情況下可能會導致子進程的內存泄露。另外,子進程中的線程可能無法訪問(父進程中)由其他線程所創(chuàng)建的線程局部存儲變量,因為(子進程)沒有任何相應的引用指針。

由于這些問題,推薦在多線程程序中調用fork()的唯一情況是:其后立即調用exec()函數(shù)執(zhí)行另一個程序,徹底隔斷子進程與父進程的關系。由新的進程覆蓋掉原有的內存,使得子進程中的所有pthreads對象消失。

對于那些必須執(zhí)行fork(),而其后又無exec()緊隨其后的程序來說,pthreads API提供了一種機制:fork()處理函數(shù)。利用函數(shù)pthread_atfork()來創(chuàng)建fork()處理函數(shù)。pthread_atfork()聲明如下:

 

#include pthread.h>

// Upon successful completion, pthread_atfork() shall return a value 
of zero; otherwise, an error number shall be returned to indicate the error.
// @prepare 新進程產生之前被調用
// @parent  新進程產生之后在父進程被調用
// @child    新進程產生之后,在子進程被調用
int pthread_atfork (void (*prepare) (void), void (*parent) (void), void 
(*child) (void));

該函數(shù)的作用就是往進程中注冊三個函數(shù),以便在不同的階段調用,有了這三個參數(shù),我們就可以在對應的函數(shù)中加入對應的處理功能。同時需要注意的是,每次調用pthread_atfork()函數(shù)會將prepare添加到一個函數(shù)列表中,創(chuàng)建子進程之前會(按與注冊次序相反的順序)自動執(zhí)行該函數(shù)列表中函數(shù)。parent與child也會被添加到一個函數(shù)列表中,在fork()返回前,分別在父子進程中自動執(zhí)行(按注冊的順序)。具體事例可參考:http://blog.chinaunix.net/uid-26885237-id-3210394.html

四、總結

fork()函數(shù)的調用會導致在子進程中除調用線程外的其它線程全都終止執(zhí)行并消失,因此在多線程的情況下會導致死鎖和內存泄露的情況。在進行多線程編程 的時候盡量避免fork()的調用,同時在程序在進入main函數(shù)之前應避免創(chuàng)建線程,因為這會影響到全局對象的安全初始化。線程不應該被強行終止,因為 這樣它就沒有機會調用清理函數(shù)來做相應的操作,同時也就沒有機會來釋放已被鎖住的鎖,如果另一線程對未被解鎖的鎖進行加鎖,那么將會立即發(fā)生死鎖,從而導 致程序無法正常運行。

以上就是腳本之家分享給大家的關于Linux下的多線程編程和fork()函數(shù)詳解的全部內容,希望對大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站其他相關專題,如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!

標簽:玉林 紹興 大連 茂名 汕頭 陜西 泰安 遼陽

巨人網絡通訊聲明:本文標題《Linux下的多線程編程和fork()函數(shù)詳解》,本文關鍵詞  Linux,下,的,多,線程,編程,;如發(fā)現(xiàn)本文內容存在版權問題,煩請?zhí)峁┫嚓P信息告之我們,我們將及時溝通與處理。本站內容系統(tǒng)采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《Linux下的多線程編程和fork()函數(shù)詳解》相關的同類信息!
  • 本頁收集關于Linux下的多線程編程和fork()函數(shù)詳解的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    蜜桃在线一区二区三区| 欧美二区三区91| 国产成人免费视频精品含羞草妖精| 精品一区二区三区香蕉蜜桃| eeuss国产一区二区三区| 亚洲国产aⅴ成人精品无吗| 久久久久久一二三区| 欧洲色大大久久| 日韩欧美美女一区二区三区| 日韩一级片在线播放| 国产精品久久99| 日韩精品一二三| 97久久精品人人做人人爽| 欧美中文字幕一区二区三区亚洲| 欧美日韩在线观看一区二区| 久久久久久久久久久久久久久99| 亚洲欧洲日韩av| 美女精品一区二区| 91精品国产aⅴ一区二区| 综合分类小说区另类春色亚洲小说欧美| 成人av电影免费观看| av在线播放一区二区三区| 91精品国产入口| 亚洲乱码国产乱码精品精可以看| 蜜臀久久99精品久久久久久9| k8久久久一区二区三区 | 久久99精品国产.久久久久 | 欧美日韩中文字幕一区| 久久婷婷色综合| 成人国产精品免费| 在线视频观看一区| 91热门视频在线观看| 国产亚洲欧美日韩日本| 丰满少妇在线播放bd日韩电影| 久久精品人人做人人爽97| 欧洲精品一区二区三区在线观看| 久久成人18免费观看| 亚洲乱码日产精品bd| 久久久国产精品不卡| jlzzjlzz亚洲日本少妇| 精品粉嫩aⅴ一区二区三区四区| 亚洲国产一区二区三区 | 亚洲电影视频在线| 美女在线观看视频一区二区| 美国精品在线观看| 制服丝袜中文字幕一区| 日本成人在线视频网站| 一区在线观看免费| 欧美v国产在线一区二区三区| 盗摄精品av一区二区三区| 亚洲精品菠萝久久久久久久| 国产传媒一区在线| 亚洲成在人线在线播放| 91精品国产美女浴室洗澡无遮挡| 久久国产尿小便嘘嘘| 欧美激情一区不卡| 3d动漫精品啪啪1区2区免费| 欧美日韩和欧美的一区二区| 26uuu成人网一区二区三区| 国产高清精品网站| 欧美成人vps| 欧美日韩一区国产| 成人福利在线看| 日本不卡一二三| 国产精品福利一区| 精品sm在线观看| 色综合夜色一区| 国产成人精品影视| 亚洲精品国久久99热| 色婷婷综合久色| 国产成人精品亚洲777人妖| 日韩福利视频导航| 五月开心婷婷久久| 欧美午夜一区二区三区免费大片| 91影院在线观看| 亚洲h动漫在线| 亚洲欧洲成人av每日更新| 欧美日韩不卡一区二区| 色综合婷婷久久| 91久久精品一区二区三区| 国产一区二区三区在线观看免费视频 | 懂色av中文字幕一区二区三区| 香蕉加勒比综合久久| 亚洲线精品一区二区三区 | 国产日韩av一区| 国产精品亚洲综合一区在线观看| 自拍偷自拍亚洲精品播放| 国产精品久久久久久户外露出| 久久久久九九视频| 国产欧美精品一区二区三区四区 | 91麻豆成人久久精品二区三区| 9人人澡人人爽人人精品| 日韩二区三区四区| 国内精品在线播放| 成人午夜私人影院| 日本韩国欧美一区二区三区| 99久久精品一区| thepron国产精品| 国v精品久久久网| 91色乱码一区二区三区| 欧美酷刑日本凌虐凌虐| 久久精品一级爱片| 亚洲视频在线一区观看| 亚洲一区二区三区四区在线| 久久精品国产在热久久| 精品写真视频在线观看| 国产成人综合亚洲91猫咪| 色哟哟国产精品| 日韩亚洲欧美一区二区三区| 日本一区二区三区四区| 最新日韩av在线| 国产精品77777| 欧美一级精品大片| 丝袜美腿亚洲一区二区图片| 欧美日韩亚州综合| 亚洲人精品午夜| 成人av在线网站| 综合欧美一区二区三区| 成人国产精品免费网站| 日本一区二区在线不卡| 成+人+亚洲+综合天堂| 在线欧美日韩精品| 亚洲美女一区二区三区| 99精品在线观看视频| 亚洲制服欧美中文字幕中文字幕| 色偷偷88欧美精品久久久| 一区二区三区国产精华| 欧美视频中文一区二区三区在线观看| 亚洲黄一区二区三区| 婷婷成人激情在线网| 精品国产免费视频| 久久 天天综合| 亚洲欧洲精品一区二区三区不卡| 一本色道久久综合亚洲91| 日韩成人精品视频| 久久久久国产精品人| 93久久精品日日躁夜夜躁欧美| 中文字幕在线不卡视频| 91一区二区三区在线观看| 一区二区不卡在线播放 | 亚洲日本欧美天堂| 欧美视频日韩视频在线观看| 日本亚洲一区二区| 在线视频你懂得一区二区三区| 日本成人在线网站| 91亚洲资源网| 亚洲欧洲www| 色婷婷国产精品| 日本一区二区三区免费乱视频| 亚洲欧洲中文日韩久久av乱码| 一本大道av一区二区在线播放| 国产日产欧产精品推荐色| 91精品国模一区二区三区| 欧美亚洲一区二区三区四区| 一本大道av一区二区在线播放| 欧美成人猛片aaaaaaa| 国产精品福利影院| 香蕉影视欧美成人| 国产精品88888| 成人黄色在线网站| 91久久免费观看| 国产成人精品综合在线观看 | 国产精品视频免费| 91麻豆蜜桃一区二区三区| 精品亚洲成av人在线观看| 国产精品美日韩| 香蕉影视欧美成人| 97se狠狠狠综合亚洲狠狠| 高清beeg欧美| 视频一区视频二区中文| 亚洲精品国产一区二区精华液| av中文字幕在线不卡| 不卡一区二区在线| 午夜av一区二区三区| 亚洲欧洲一区二区三区| 欧美性猛片aaaaaaa做受| 国产曰批免费观看久久久| 日韩免费一区二区| 色94色欧美sute亚洲线路一ni| 91视频一区二区三区| 欧美亚洲一区二区在线| 日韩午夜激情免费电影| 国产精品成人免费精品自在线观看 | 天堂在线一区二区| 国产福利一区二区三区在线视频| 久久99国产精品久久99| 国产成人自拍网| 色屁屁一区二区| 精品久久国产字幕高潮| 亚洲国产高清不卡| |精品福利一区二区三区| 首页欧美精品中文字幕| 97超碰欧美中文字幕| 在线免费亚洲电影| 2014亚洲片线观看视频免费| 亚洲一区二区中文在线| 日韩电影免费一区| 色综合中文综合网| 国产一区二区三区黄视频 | 宅男噜噜噜66一区二区66|