2010-05-19 36 views
5

我正在使用2.6.24.3內核爲嵌入式Linux項目開發用戶空間應用程序。 我的應用程序通過創建2個pthread來在兩個文件節點之間傳遞數據,每個睡眠直到異步IO操作完成,然後喚醒並運行完成處理程序。我可以防止在關鍵代碼中產生Linux用戶空間pthread嗎?

完成處理程序需要跟蹤有多少個傳輸處於掛起狀態,並維護一個線程將添加到另一個線程並將另一個線程移除的鏈接列表。

// sleep here until events arrive or time out expires 
for(;;) { 
    no_of_events = io_getevents(ctx, 1, num_events, events, &timeout); 
    // Process each aio event that has completed or thrown an error 
    for (i=0; i<no_of_events; i++) { 
     // Get pointer to completion handler 
     io_complete = (io_callback_t) events[i].data; 
     // Get pointer to data object 
     iocb = (struct iocb *) events[i].obj; 
     // Call completion handler and pass it the data object 
     io_complete(ctx, iocb, events[i].res, events[i].res2); 
    } 
} 

我的問題是這樣的......

有一個簡單的辦法可以防止當前活動的線程產生,而它運行完成處理,而不是下降互斥/自旋鎖路線?

或者失敗了,可以配置Linux來防止在持有互斥鎖/自旋鎖時產生pthread?

回答

4

您可以使用系統調用sched_setscheduler()臨時將線程的調度策略設置爲SCHED_FIFO,然後再次設置它。從sched_setscheduler()手冊頁:

SCHED_FIFO過程運行,直至 它是由I/O請求阻擋時,它是 更高優先級 過程搶佔,或它調用sched_yield(2)

(在這種情況下,「過程」實際上是指「線程」)。

但是,這是一個相當可疑的要求。你希望解決什麼問題?如果你只是試圖保護你的鏈表完成處理程序免受併發訪問的影響,那麼普通的互斥量就是要走的路。讓完成線程鎖定互斥鎖,刪除列表項,解鎖互斥鎖,然後調用完成處理程序。

+0

該要求主要是試圖保持代碼簡單,有幾個項目需要在完成處理程序中互斥,但如果您可以確保它只會在處理程序之外產生,我認爲您不需要任何。 我想另一種選擇是在整個處理程序周圍放一個粗糙的互斥體。 – KermitG 2010-05-19 15:10:33

+4

@KermitG:如果您擔心完成處理程序代碼本身與另一個線程中的代碼競爭,那麼只需防止搶佔將無濟於事。當完成處理程序啓動時,另一個線程可能已經在臨界區內;即使在完成處理程序運行時暫停它,它仍然會看到它正在處理的數據將從其下方更改。通常,如果處理程序中的代碼可以競爭,則處理程序本身應負責鎖定。 – caf 2010-05-19 21:47:49

1

我想你會想在這裏使用互斥/鎖來防止競爭條件。互斥體絕不是巫術魔法,甚至可以使您的代碼更簡單,而不是使用任意系統特有的功能,這些功能您可能需要跨系統進行端口連接。不過,不知道後者是否是你的問題。

1

我相信你在這裏試圖超越Linux調度器,原因是錯誤的。

正確的解決方案是使用互斥鎖來防止並行處理完成處理程序。讓調度程序完成它的工作。

相關問題