日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

muduo学习笔记 - 第4章 C++多线程系统编程精要

發布時間:2024/4/18 c/c++ 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 muduo学习笔记 - 第4章 C++多线程系统编程精要 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

第4章 C++多線程系統編程精要

  • Pthreads只保證統一進程之內,同一時刻的各個線程的id不同,不能保證同一進程先后多個進程具有不同的id,更不要說一臺機器上多個進程之間的id唯一性,pthread_t不適合用做程序對線程的標識符。

  • 推薦使用**gettid()**的返回值作為線程id

    • 返回值類型pid_t,通常是小整數,便于在日志輸出
    • 可以在/proc文件系統中找到對應項,/proc/tid,/proc/pid/task/tid
    • 任何時候全局唯一
    • top判斷CPU占有最高的線程id
    • pid = 0非法,系統的第一個進程init的pid = 1

4.1 線程的創建和銷毀應該遵循的原則

  • 程序庫不應該在未提前告知的情況下創建自己的“背景線程”
  • 盡量用相同的方式創建線程
  • 在進入main()函數之前不應該啟動線程
  • 程序中線程的創建最好能在初始化階段全部完成

4.2 線程的銷毀方式

  • 自然死亡,從線程主函數返回,線程正常退出
  • 非正常死亡,從縣城主函數拋出異常或線程觸發segfault信號等非法操作
  • 自殺,在線程中調用pthread_exit()來立刻退出線程
  • 他殺,其他線程調用pthread_cancel()來強制終止某個線程

線程正常退出的方式只有一種,自然死亡。強制終止線程的話,沒有機會清除所有的資源,也沒有機會釋放已經持有的鎖,其他線程如果對同一個mutex加鎖,那么他就會立刻死鎖。

如果程序中線程的創建能在初始化階段全部完成,線程是不必銷毀的,伴隨程序的一直運行,徹底避開了線程安全退出可能面臨的各種困難

4.3 exit在C++中不是線程安全的

exit()函數在C++中的作用除了終止進程,還會析構全局對象和已經構造完的函數靜態對象。這回潛在的死鎖可能

void someFunctionMayCallExit() {exit(1); } class GlobalObject { public:void doit() {MutexLockGuard lock(mutex_);someFunctionMayCallExit();}~GlobalObject() {printf("GlobalObject: ~GlobalObject\n");MutexLockGuard lock(mutex_); // 死鎖//clean upprintf("GlobalObject:~GlobalObject cleanning\n");} private:MutexLock mutex_; };GlobalObject g_obj; int main() {g_obj.doit(); }

4.4 多線程與IO

  • 多線程與IO可能存在的問題:

    • 線程正在阻塞read()某個socket,另一個線程close()這個socket

    • 線程正在阻塞的accept()某個listening socket,另一個線程close()這個socket

    • 線程準備read()某個socket,另一個線程close()socket,第三個線程又open()了相同的fd的socket。POSIX標準要求每次新打開的文件使用當前最小的可用的文件描述符

  • 為什么服務端程序不應該關閉標準輸出和標準出錯?

    有些第三方庫會向stdout和stderr打印出錯信息,如果程序關閉了標準輸入和標準出錯,可能被網絡連接占用,造成對方收到莫名其妙的數據。正確的做法是把stdout和stderr重定向到磁盤文件

4.5 多線程與fork

fork()之后,子進程繼承了父進程的幾乎全部狀態,有些少數例外。子進程會繼承地址空間和文件描述符。

子進程不會繼承的有:

  • 父進程的內存鎖,mlock,mlockall
  • 父進程的文件鎖,fcntl
  • 父進程的某些定時器,setitimer,alarm,timer_create
  • 其他

fork()之后子進程只有一個線程,其他線程都消失了。這可能存在隱患:一些線程持有鎖處于臨界區,而子線程試圖對同一個mutex加鎖,這會造成死鎖。

fork()之后,子進程不能調用:

  • malloc,malloc在訪問全局狀態時,幾乎肯定會加鎖
  • 任何可能分配或釋放內存的函數,new,map::insert(),snprintf
  • 任何pthread函數
  • printf函數,其他線程可能恰好持有stdout/stderr鎖
  • 除了signal安全函數之外的任何函數

唯一安全的做法是在fork()之后立即調用exec()執行另一個程序,徹底隔斷子進程與父進程的聯系

總結

以上是生活随笔為你收集整理的muduo学习笔记 - 第4章 C++多线程系统编程精要的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。