簡體   English   中英

異步/等待代碼中的競爭條件

[英]Race Condition in Async/Await Code

我只是想知道下面的代碼中是否出現競爭條件:

int readingFiles;
async Task<string> ReadFile (string file)
{    
    ++readingFiles;

    var text = await Stream.ReadFileAsync(file);

    --readingFiles;

    return text;
}

如果線程池線程執行ReadFile方法,則readFiles將由兩個不同的線程訪問,而readingFiles變量不受任何同步慣用法的保護。

這意味着對於執行“--readingFiles”的其他線程,readFiles的第一次更新不應該是可見的。 但是,在“--readingFiles”之后,我從未見過readFiles等於-1。 我檢查同一個線程是否使用Thread.CurrentThread執行++和 - 操作。 在大多數情況下,它不是同一個線程,我仍然沒有看到readingFiles為-1。

即使存在競爭條件且readingFiles不易變,為什么我不能看到這種競爭條件的影響?

這里沒有競爭條件。 .NET運行時將插入適當的內存屏障。

另請參閱以下評論: http//blogs.msdn.com/b/pfxteam/archive/2012/04/12/async-await-faq.aspx

是的,當任務排隊時以及任務執行的開始/結束時,TPL包含適當的障礙,以使值適當地可見。

這里有許多事情可以發生。

首先,你運行什么樣的可執行文件? 當Await觸發時,它使用當前的同步上下文,因此您等待的代碼可能被序列化為1個UI線程。

此外,由於變量周圍沒有內存屏障/波動保護,您的線程可能正在讀取單獨緩存的值(如@ Spo1ler在其帖子中所述)

此外,線程池可能選擇在同一個線程上運行您的請求(這是在其權限范圍內 - 您讓.net / windows決定何時以及如何分配線程)

但最重要的是,您確實應該通過同步或互鎖操作來保護對變量的訪問。

暫無
暫無

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

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