linux 下進程間的同步機制有哪些?

今天面試,面試官問了這個問題,我的回答是:互斥量,讀寫鎖,信號量,臨界區,條件變數。面試官說只有一個是正確的,然後我就不知道其他的了。面試官最後說還有管道,匿名管道,共享內存,套接字。不太懂,求解 _______________________________________ 百度上面幾乎所有的回答都是我說的這幾個,沒有面試官所說的這些。。。。。。


Perl大駱駝書講了很多IPC機制:

  • 用文件裸奔:文件的存在與否來當鎖,文件內容來交互數據;
  • 匿名管道;
  • semaphore,shared memory;
  • Unix socket,本機的TCP socket;
  • 對了,還有最基本的進程signal。


1. 你的答案確實是錯的,很多人解釋過了,人家問的是進程間同步,你回答的是線程間同步的機制

2. 但你們不要當那種考試考傻了的書獃子,把「同步」和「通訊」的概念分得那麼清楚,能通訊就一定是一種同步機制,這是顯而易見的。

3. 最後,如果你描述沒有錯,你面對的這個面試官也是個半桶水的。我們做面試,首先考慮的不是問題應該怎麼作答,我們首先考慮的是你能解決什麼問題,眼看你理解題意有誤,我的做法是直接告訴你這個知識點,然後繼續了解你對這個問題有多深,而不是為了難住你。而至於面對一個逗比面試官應該如何做,這是另一個主題了,你需要另找答案或者單獨設問。


信號,信號量,消息,共享內存,文件系統

至於管道和網路……還是加上吧……

面試官沒有說消息啊……


面試官說的是通信機制啊


進程間同步,可移植性最好的還是文件鎖。


你的這些回答大多是用於線程,或者說進程內同步。

這些方法大多對進程與進程間沒法用或者不是常規用法。面試官很顯然無誤的是指的進程間,你的回答當然不準確,進程間確實一般不會用這種方法同步。

糾結通訊還是同步概念的各位,以及認為題主沒錯的各位,您們真覺得題主那些方法都適合用於進程?

我不認為一個靠譜的教科書會告訴你用這些方法是實現進程間同步的標準方法。如果題主所說為真,我對現在教材的素質感到擔憂。


進程之間傳遞信息的各種途徑(包括各種IPC機制)總結如下:

  • 父進程通過fork可以將打開文件的描述符傳遞給子進程
  • 子進程結束時,父進程調用wait可以得到子進程的終止信息
  • 幾個進程可以在文件系統中讀寫某個共享文件,也可以通過給文件加鎖來實現進程間同步
  • 進程之間互發信號,一般使用SIGUSR1和SIGUSR2實現用戶自定義功能
  • 管道
  • FIFO mmap函數,幾個進程可以映射同一內存區
  • SYS V IPC,以前的SYS V UNIX系統實現的IPC機制,包括消息隊列、信號量和共享內 存,現在已經基本廢棄
  • UNIX Domain Socket,目前最廣泛使用的IPC機制


面試官說的是對的。參考APUE進程間通信一章引言部分的那張表。你的回答大多是線程同步機制。

進程是相互獨立的,所以進程間通信大多不需要鎖,需要的鎖也是文件鎖之類的「大鎖」,並不需要條件變數、互斥鎖這些機制來同步,進城之間對資源的使用由操作系統的進程調度部分來完成。線程需要互斥鎖的原因是,除了線程棧里的東西其他都是共享的,需要你自己來完成變數級別的同步。

------------------------

另外,線程之間的叫同步,進程之間的叫通信。


看來是基礎不夠紮實,題主我建議你把問題中提到的每個名詞單獨搜索學習一遍,全部搞懂再去面試。不然面上了實際工作也堪憂啊。


我覺得,要麼是面試官說錯了,要麼是你聽錯了。

他的答案所對應的題面應該是IPC,就是進程間通信。

你的答案所對應的題面應該是進程同步。其實,也不一定是進程了。任何可調度的作業,都可以使用信號量,讀寫鎖等等辦法來控制。比如,哲學家吃飯(誤),比如工廠訂單分配等等,不一定與計算機相關。


我的書第3.4節:進程間通信只用 TCP。


請不要背書,很多時候自己背錯了書都不知道。你的答案是線程同步機制……

各位說進程間只有通信,線程才需要同步的,還說人家面試官錯了的,其實都是在背書……

進程間也有同步問題,而IPC是同步的實現手段。

如果我去面試,我回答:「我記不住那麼多,我可以試著說幾個,真需要用了,我會去翻APUE,選擇最合適的IPC方式」。不知道各位做面試官的評價如何?


信號量是對的吧, 進程間內存空間獨立所以必須要走OS,中文不好用只能上英文,Inter-process communication


你把競爭與並發說了一遍。應該PK掉你。


文件, Pipe, fifo, 消息隊列, 信號量, 共享存儲和socket , 我都沒學會


你的題目寫的是進程同步,而面試官的說的都是進程通訊。是兩碼事。不知道是你誤解了面試官的意思,還是面試官自己搞錯了。

通訊有很多方式

1)管道

2)共享內存

3)消息隊列

4)Socket

等,只要能交流就可以了。這個是IPC(Inter Process Communication)

而同步的方式主要是

1)Mutex(互斥)可以跨進城使用

2)Semphore(信號量)可以跨進城使用

兩者適用範圍場合依據需求決定

PS:事件拿來控制同步也可以,說他是一個通訊方式也可以。

如果配合起來可以是:

Case 1)

進程A將資料寫入共享內存(使用Mutex加鎖)

進程B從共享內存中讀資料(也使用Mutex加鎖)

Case 2)使用Semaphore實現的讀寫鎖

進程A將資料寫入共享內存(加寫鎖)

進程B從共享內存中讀資料(加讀鎖)

性能比上面的好很多。

.NET寫共享內存的時候盡量寫入基本數據類型或者Structure數據效率較高,避免大範圍的系列化反序列化的動作影響性能。避免共享內存中又臟數據。

手機碼字回答的不夠全面還請見諒。


面試官錯了,通信是通信,同步是同步


進程間通信機制:信號、管道、Socket

互斥量:多線程訪問臨界區時使用

讀寫鎖:資料庫;多線程共享資源訪問

條件變數:與互斥量一起,在多線程訪問共享區域時,通知其他線程條件滿足


既然說線程的同步,那就不要多談線程進程的區別了,那是跑題。只談論線程的同步。

有個答案說得好,同步和非同步,指的是順序問題。一件事完成後,再做下一件事。A走一步,等B走一步,A再走一步。這就是同步。同步和非同步關注的是業務層面的抽象設計,而非操作系統底層,在操作系統底層的概念是休眠、喚醒、搶佔、中斷、阻塞和非阻塞。線程之間當然也常常要同步的,比如用戶線程與內核IO、比如中斷處理、比如fork()之後的父子線程。再比如要用金山遊俠修改遊戲里的金錢,你打開遊戲,看看錢,金山遊俠掃描內存,進遊戲買點東西,再看看錢,再掃描內存,最後修改金錢。這不就是人工同步嗎。

進程間同步的方法其實是利用了進程通信的方法。例如信號(kill、signal)控制進程的運行、信號量控制進程對共享內存的修改、文件鎖等等。嚴格說來,消息隊列、管道、socket是通信方法,進程間交換數據,用來做進程間同步是可行但不太實用的,除非某些複雜的場景。比如socket通信,如果要用socket通信來同步兩個進程,那當然可以。比如一個進程讀一個進程寫,讀進程阻塞,直到另一個進程給他寫一句"go go go
",然後才繼續下一步。這就是進程之間的同步。

另外要分清同步、非同步、阻塞、非阻塞的區別。同步是A等待B完成再執行;非同步是A通知B執行後立即返回,自己處理其他事情,等B完成後再取回結果。阻塞是進程休眠等待內核;非阻塞是用戶進程立即返回後再輪詢,或者等待信號或回調。輪詢是同步非阻塞,信號或回調是非同步非阻塞。而實際上,非同步也可能是靠線程池+阻塞IO實現,也可能是靠事件隊列+事件回調實現。所以說,同步非同步是個業務邏輯問題。但既然問題是線程的同步,那就只談線程的同步就夠了。

參考《Linux/Unix系統編程手冊》第43章。


面試官說的是進程間的通信機制IPC,你的回答沒有錯。


推薦閱讀:

殭屍進程和僵死進程有什麼區別?
Linux/Windows在多CPU時控制CPU使用率時表現為什麼不同?
你有可能買一台 Chromebook 么?
深度學習工具caffe在windows上的性能表現真的沒有在Linux上好嗎?
從 X86 到 ARM 的移植,為什麼 Windows 的兼容性看起來沒有像Linux、OS X那樣好?

TAG:程序員 | 編程 | Linux | 網路編程 | 進程 |