linux操作系统之线程
(1)線程(LWP)? ?可使用命令查看指定線程的LWP號:? ps? -Lf pid
? ? ? ? ? ? 1)light weigh process(輕量級進程),本質上仍然是進程
? ? ? ? ? ? ? ? ? ? ? ?進程:獨立的地址空間,擁有PCB,最小分配資源單位,內存分配資源以進程為標準。
? ? ? ? ? ? ? ? ? ? ? ?線程:沒有獨立的地址空間(共享),擁有PCB,最小的執行單位,CPU分配時間輪片是以線程為標準。
? ? ? ? ? ? 2)線程和進程的聯系和區別
? ? ? ? ? ? ? ? ? 1>線程也有PCB,創建線程使用的底層函數和進程一樣,都是clone。
? ? ? ? ? ? ? ? ? 2>從內核里看進程和線程都是一樣的,都有各自不同的PCB,但PCB中指向內存的三級頁表是相同的(類似于指向相同內存的指針,指針不同,但是內存相同)。
? ? ? ? ? ? ? ? ? ? ? ?三級映射:進程PCB--->頁目錄(4kb)-->頁表---->物理頁面---->內存單元
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? ? 3>進程可以退變成線程。
? ? ? ? ? ? ? ? ? 4>線程可以看做寄存器和棧的集合
? ? ? ? ? ?3)線程資源和優缺點
? ? ? ? ? ? ? ? ? ? ?1)共享資源
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?文件描述符? 信號處理方式? ?工作目錄? 用戶id和組id? ? ? 內存地址空間(除棧空間和errno變量)
? ? ? ? ? ? ? ? ? ? 2)獨享資源
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 線程id? ?處理器現場和棧指針(內核棧)和獨立的棧空間(用戶棧 )? errno變量? ? 信號屏蔽字? 調度優先級
? ? ? ? ? ? ? ? ? ? 3)線程優缺點
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?優點:提高程序并發性? 開銷小(針對于進程)? 數據通信共享數據方便(進程:IPC通信)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?缺點:使用庫函數,不穩定? ?調試編譯困難,gdb不支持(出現在gdb之后)? ?對信號支持不好
(2)線程控制原語
? ? ? ? ? ?1)獲取線程id:? pthread_t pthread_self(void);? ? ? ? ? ? ? ? ? ? ?---->對應進程getpid()
? ? ? ? ? ? ? ? ? ? ? ? ?pthread_t? pthread_self(void);? ? ? ? ? ? 返回值:成功 0? ? ?失敗? 無
? ? ? ? ? ? ? ?pthread_t:為linux下的無符號整數(%lu)
? ? ? ? ? ? ? ?線程ID為進程內部,識別標志,兩個進程之間線程id允許相同。
? ? ? ? ?2)創建一個新線程 :pthread_create? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? --->對應進程的fork()
? ? ? ? ? ? ? ? ? ? int pthread_create(pthread_t *thtrad,const pthread_attr_t *attr,void*(*start_routinue)(void *),void *arg);
? ? ? ? 返回值? ?成功:0? ? ?失敗:錯誤號(linux環境下線程的特點:失敗均返回錯誤號,不能使用perror,而應該使用sterror函數)
? ? ? ? ?參數? ? ? ? ? ? ? 1:保存系統為分配的線程id
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?2:通常設置為NULL,表示使用線程的默認屬性(可使用具體參數修改該參數)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?3:函數指針,指向線程主函數(線程體)。函數運行結束,則線程結束。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?4:主函數執行期間所使用的參數。
? ? ? ? ? 使用pthread_create循環創建多個線程,每個線程打印自己是第幾個被創造的線程
? ? ? ? ? ? ? ? 1>實現和結果
? ? ? ? ? ? ? ?
? ? ? ? ? ? ??? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ? 直接將整形轉化為指針類型,如果是32位的操作系統,直接轉換。如果是64位的操作系統,則是小端轉大端問題,前頭補零,數據不變化。
? ? ? ? ? ? ?2>代碼修改:(換成取地址,符合我們正常的理解,結果有問題)
? ? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? ? 如果是取地址的話,則線程去i的時候可能其他的線程也來了,此時兩個線程公用全局變量,使得兩個i值混亂。可以直接利用兩個線程之間不共享棧的特點,直接采用值傳遞,而不是址傳遞。
? ? ? ? ? ?3)單個進程退出:pthread_exit函數
? ? ? ? ? ? ? ? ? void? pthread_exit(void* retval)? 參數:retval 表示線程退出狀態,通常傳NULL
? ? ? ? ? 在多線程中 exit ,return ,pthread_exit的區別:
? ? ? ? ? ? ? ? ?exit:進程中的所有線程退出,在線程中應該禁止使用exit.
? ? ? ? ? ? ? ? ?return:返回到調用者那里,繼續執行下一步程序。
? ? ? ? ? ? ? ? pthread_exit:退出單個線程
? ? ? ? ? 結論:多線程環境中,應該盡量不用或者少用exit函數,取而代之用pthread_exit函數。pthread_exit或者return返回的指針所指向的內存必須是全局或者malloc分配的(不同線程不共享棧)
? ? ? ? ? 4)阻塞等待線程退出,獲取線程退出狀態 :pthread_join? ? ? ? ? ? ? ? ? ? ? ? ?---->對應進程中的waitpid()
? ? ? ? ? ? ? ? ? ? int? pthread_join(pthread_t thread,void **retval);? ? ?成功:0? 失敗:錯誤號
? ? ? ? ? ? ?參數:線程id? ,retavl:儲存線程結束狀態。
? ? ? ? 5)線程分離:pthread_detach(常用與網路和多線程服務器)
? ? ? ? ? ? ? ? ? ?int? ?pthread_detach(pthread_t thread)? ? ? ?成功:0? 失敗:錯誤號
? ? ? ? ? ? ? ? ? ?線程分離:線程主動與主控線程斷開聯系。線程結束后,其退出狀態不由其他線程獲取,而是自己主動釋放(不會產生僵尸進程)(也可以通過pthread_create 通過設置參數2實現線程分離)
? ? ? ? ? ? ? ? 使用了線程分離的線程不能夠在使用pthread_join,這樣調用返回EINVAL錯誤
? ? ? ?6)殺死(取消)線程:pthread_cancel函數? ? ? ? ? ? ? ? ? ? --->進程的kill函數
? ? ? ? ? ? ? ? ?int pthread_cancel(pthread_t thread);? ??? ? ???成功:0? 失敗:錯誤號
? ? ? ? ? ?注意:線程的取消和殺死并不是實時的,而是有一定的延時性,需要等待線程到底某個取消點或者檢查點(通常是系統調用,可通過 man 7 pthread查看取消點列表,也可以通過pthread_testcancel()函數來自行設置一個取消點)
? ? ? ? 當我們對一個已經取消的線程使用pthread_join時,返回值是-1.
? ? ? ? ?終止線程的方式:
? ? ? ? ? ? ? ? ? ? ? ?1>線程主函數return 返回,不適用于主控線程。
? ? ? ? ? ? ? ? ? ? ? ?2>一個線程調用pthread_cancel終止同一個進程中的另一個線程。
? ? ? ? ? ? ? ? ? ? ? ?3>線程可以調用pthread_exit終止自己。
總結
以上是生活随笔為你收集整理的linux操作系统之线程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 镜花水月第一季剧情介绍
- 下一篇: 女性不孕症可以做人工怀孕吗