Linux中多進程(多線程)編程

多進程編程
一、複製進程映像的fork系統調用
1)

父進程返回子進程的PID,子進程返回0
2)寫時拷貝
子進程與父進程代碼完全一致,同時它還會複製父進程的數據(堆數據,棧數據及靜態數據),採用寫時拷貝技術,只有在任一進程對數據進行了讀寫操作時,拷貝纔會發生。

 二、exec 系列系統調用
  在子進程中執行其他程序,即替換當前進程映像                                                                                                                                                                                                                                                                                                                                                                                                  
1) 系統調用exec是以新的進程去代替原來的進程,但進程的PID保持不變。
因此,可以這樣認爲,exec系統調用並沒有創建新的進程,只是替換了原來進程上下文的內容。原進程的代碼段,數據段,堆棧段被新的進程所代替。

一個進程主要包括以下幾個方面的內容:
(1)一個可以執行的程序
(2) 與進程相關聯的全部數據(包括變量,內存,緩衝區)
(3)程序上下文(程序計數器PC,保存程序執行的位置)
 
exec 是一個函數簇,由6個函數組成,分別是以excl和execv打頭的。具體如下:
execl (const char* filepath,const char* arg1,char*arg2......)
execlp (const char*filename,const char*arg1,const char*arg2..... )
execle (const char*filepath,const char*arg1,const char*arg2,.....,char* cons envp[])
execv  (const char* filepath,char* argv[])
execvp (const char* filename,char* argv[])
execve (const char* filepath,char*argv[],char* const envp[])
path參數制定可執行文件的完整路徑,file參數可以接收文件名,envp參數用於設置新程序的環境變量,只有execve是真正意義上的系統調用,其它都是在此基礎上經過包裝的庫函數。
一般情況下,exec函數是不返回的,出錯返回-1.若沒有出錯,則原程序中exec調用之後的代碼都不會執行 ,因爲此時源程序已經被exec的參數制定的程序完全替代
exec函數不會關閉源程序打開的文件描述符的
三、處理殭屍進程
見關於進程的筆記

多線程編程(Linux下)  <pthread.h>
一、線程模型
線程是程序中完成一個獨立任務的完整執行序列,是一個可調度的實體
內核線程,運行在內核空間,油內核來調度;用戶線程運行在用戶空間,由線程庫來調度;內核線程相當於用核線程運行的的容器。
一個進程可以包含M個內核線程和N個用戶線程,M<=N
線程的實現分爲:
完全在用戶空間實現:優點:無需內核干涉不佔用額外的內核資源;缺點:對於多處理器系統,一個進程的多個線程無法運行在不同的CPU上
完全由內核調度      雙層調度(充分利用多次處理器的優勢)
二、創建線程和結束線程
1、創建線程:
int  pthread_create(pthread_t*  thread, const  pthread_attr_t* arr,  void* (*start_routine)(void*), void  arg);
2、退出線程:void   pthread_exit(void *retval);
3、回收其他線程:int  pthread_join(pthread_t  thread, void **retval);
一直阻塞直到被回收的線程結束爲止
4、取消該線程:int  pthread_cancel(pthread_t  thread);  //成功返回0
三、用於線程同步的機制:POSIX信號量    互斥量   條件變量
1、信號量

2、互斥鎖
1)

pthread_mutex_lock:加鎖操作,如果目標鎖已被鎖上,將會阻塞,直到解鎖
pthread_mutex_unlock:解鎖操作,如果此時有其他線程正在等待這個互斥鎖,則這些線程中的某一個將會獲得它
pthread_mutexattr_t  結構體定義了一整套完整的互斥鎖屬性
互斥鎖的兩種常用屬性:pshared(指定是否允許跨進程共享互斥鎖)  
type(制定互斥鎖的類型:普通鎖、檢錯鎖、嵌套鎖、默認鎖)
2)死鎖:指兩個或者兩個以上的進程在執行過程中,因爲爭奪資源而造成的一中互相等待的現象,若無外力作用,他們都將無法推進下去
產生死鎖的原因:
1)因爲系統資源不足
2)進程運行推進的順序不合適
3)資源分配不當等
產生死鎖的必要條件:
1)互斥條件:一個資源每次只能被一個進程使用
2)請求與保持條件:一個進程因請求資源而阻塞時,對已獲得的資源保持不放
3)不剝奪條件:進程已獲得的資源,在未使用完之前,不能強行剝奪
4)循環等待條件:若干進程之間形成一種頭尾相接的循環等待資源
死鎖的處理方法:
1)預防死鎖:破壞產生死鎖的四個必要條件衆多的一個或幾個,可能會導致系統資源利用率和吞吐量降低
2)避免死鎖:在資源的動態分配過程中,用某種方法去防止系統進入不安全狀態
3)檢測死鎖:此方法允許系統在運行過程中發生死鎖。但可通過系統所設置的檢測機構,及時地檢測出死鎖的發生,並精確地確定與死鎖有關的進程和資源,然後採取適當措施,從系統中將已發生的死鎖清除掉。
4)解除死鎖 :撤銷或掛起一些進程,以便回收一些資源,再將這些資源分配給已處於阻塞狀態的進程,使之轉爲就緒狀態,以繼續運行。
死鎖:1)在一個線程中對一個已經加鎖的普通鎖再次加鎖
          2)兩個線程按照不同的順序來申請兩個互斥鎖
3、條件變量:用於在線程之間同步共享數據的值
當某個共享數據達到某個值的時候,喚醒等待這個共享數據的線程

四、多線程環境
1、可重入函數:如果一個函數能被多個線程調用且不發生競態條件,則是線程安全的,即是可重入函數
2、線程和進程
在多線程環境中,提供pthread_atfork函數,確保fork調用後父進程和子進程都擁有一個清楚地鎖狀態(見P302)
明確的將一個信號發送給指定的線程:int  pthread_kill(pthread_t  thread,  int  sig);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章