簡體   English   中英

如何從strace輸出確定程序的哪一部分無法獲取互斥鎖

[英]How do I determine from strace output what part of my program is failing to acquire a mutex

我正在一個嵌入式Linux系統(3.12.something)上工作,經過一段時間,我們的應用程序開始占用CPU。 我已經在我們的應用程序上運行了strace ,並且當問題發生時,我在strace輸出中看到很多與此類似的行:

[48530666] futex(0x485f78b8, FUTEX_WAIT_PRIVATE, 2, NULL) = -1 EAGAIN (Resource temporarily unavailable) <0.009002>

我很確定這是我正在尋找的吸煙槍,並且有某種比賽。 但是,我現在需要弄清楚如何在試圖獲取此互斥鎖的代碼中標識該位置。 我怎樣才能做到這一點? 我們的代碼是使用GCC編譯的,並且其中包含調試符號。

我目前的想法(我還沒有嘗試過)是在嘗試獲取系統中的任何互斥鎖之前,先將一個字符串輸出到stdout並刷新,以期該字符串將在strace抱怨獲取鎖之前打印出來。但是,在代碼中有很多地方必須像這樣進行檢測。

編輯:我剛剛意識到的另一件奇怪的事情是,我們的程序直到運行了一段時間(5分鍾到5小時以及介於兩者之間的任何時間),才開始占用CPU。 在此期間,發生了零次 futex系統調用。 他們為什么突然開始? 根據我的閱讀,我認為也許它們已經在用戶空間中正確使用,直到出現故障並退回到進行futex() syscall為止。

有什么建議么?

如果您永久性地並經常將互斥鎖從不同的線程鎖定一小段時間,例如保護全局記錄器,則可能會導致所謂的線程保護。 在兩個線程爭奪鎖之前,不會發生此問題。 第一個獲得該鎖並保持一小段時間,然后,當第二次需要該鎖時,它被搶占,因為第二個已經在等待。 第二個相同。 每個線程可用的時間片突然減少到兩次鎖定嘗試之間的時間,從而導致許多上下文切換和相應的速度降低。 此外,除一個線程外,所有線程始終在互斥體上被阻止,從而有效地禁用了任何並行執行。

為了解決這個問題,讓您的線程合作而不是爭奪資源。 對於記錄器的上述示例,請考慮例如使用線程本地存儲的條目的無鎖隊列或每個線程的單獨隊列。

關於futex()調用,其想法是輪詢一個原子標志,並在進行一些旋轉后使用實際的OS互斥鎖。 無需在用戶空間和內核空間之間進行昂貴的切換即可使用原子標志。 對於更長的中斷,使用內核搶占(與futex() )可以避免通過輪詢阻塞CPU。 這解釋了為什么程序在正常操作中不需要任何futex()調用。

您,此時基本上需要生成核心文件。

然后,您可以在GDB中加載program + core並進行查看

man gcore

要么

generate-core-file

在此期間,發生了零次futex系統調用。 他們為什么突然開始?

這是由於這樣的事實,即通過futex實現的無競爭的互斥體不會純粹在用戶空間中進行系統調用,而只會進行原子增量。 系統調用中僅顯示CONTESTED鎖

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM