簡體   English   中英

boost.asio-如果在不同的異步處理程序之間共享數據庫類型的對象,是否需要使用鎖?

[英]boost.asio - do i need to use locks if sharing database type object between different async handlers?

我正在為項目制作一台小型服務器,我有一個日志處理程序類,其中包含一個實現為映射的日志以及一些對其執行操作的方法(添加條目,刷新到磁盤,提交等)。

該對象在服務器Class中實例化,我將地址傳遞給會話,以便每個會話都可以向其中添加條目。

會話是異步的,日志寫入將發生在async_read回調中。 我想知道這是否會成為問題,是否需要使用鎖?

映射格式為map<transactionId map<sequenceNum, pair<head, body>> ,每個會話將訪問不同的transactionId,因此,據我所知,應該沒有沖突。 同樣假設,如果它們都寫到內存中的同一位置,則其大小足以使該操作不會成為原子操作。 我需要鎖嗎? 據我了解,每個異步方法都會調度一個線程來處理該操作,這使我假設是。 同時,我讀到異步功能的一大用途是不需要同步原語的事實。 所以我有點困惑。

第一次使用ASIO或任何類型的異步函數,我不是一個非常有經驗的編碼器。 我希望這個問題有道理! 到目前為止,該代碼似乎運行良好,但是如果正確,我會很好奇。

謝謝!

異步處理程序僅在通過run()run_one()poll()poll_one()處理io_service事件循環的應用程序線程中調用。 文檔指出:

異步完成處理程序將僅從當前正在調用io_service::run()線程中調用。

因此,對於非線程安全共享資源:

  • 如果應用程序代碼只有一個線程,則既沒有並發也沒有競爭條件。 因此,不需要其他形式的同步。 Boost.Asio將此稱為隱式
  • 如果應用程序代碼具有多個處理事件循環的線程,並且共享資源僅在處理程序中訪問,則需要進行同步,因為多個線程可能會嘗試同時訪問共享資源。 要解決此問題,可以執行以下任一操作:
    • 通過諸如互斥鎖之類的同步原語保護對共享資源的調用。 這個問題涉及在處理程序中使用互斥鎖。
    • 使用同一鏈來wrap() ReadHandlers。 一個strand將阻止並發調用通過它分配的處理程序。 有關使用絞線的更多詳細信息,尤其是對於組合操作,例如async_read() ,請考慮閱讀答案。
    • 與其將整個ReadHandler張貼到該鏈中,不如將與共享資源的交互限制為一組特定的函數,並且這些函數作為CompletionHandlers張貼到同一鏈中。 此解決方案與先前解決方案之間的細微差別是同步的粒度。
  • 如果應用程序代碼具有多個線程,並且從處理事件循環的線程和未處理事件循環的線程訪問共享資源,則需要使用同步原語,例如互斥鎖。

同樣,即使共享資源足夠小以至於寫入和讀取始終是原子的,也應該使用顯式和適當的同步。 例如,盡管寫入和讀取可能是原子的,但沒有適當的內存防護來保證內存可見性,但即使實際內存有機會,線程也可能不會觀察到內存中的機會。 Boost.Asio將執行適當的內存屏障以確保可見性。 有關Boost.Asio和內存障礙的更多詳細信息,請考慮閱讀答案。

暫無
暫無

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

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