簡體   English   中英

如何處理此(db)隊列競爭條件?

[英]How to handle this (db) queue race condition?

基本上我有多個線程通過SQLite將數據添加到隊列中。 我有另一個線程可以拉動它們並一次處理它們(太多的資源無法一次執行多個)。 處理線程執行此操作:

  1. 從數據庫中提取數據
  2. foreach {處理}
  3. 如果count == 0 {thread.suspend()}(被thread.resume()喚醒)
  4. 重復

我的工作線程可以:

  1. 驗證數據
  2. 插入數據庫
  3. 調用Queue.Poke(QueueName)

當我戳它時,如果線程被掛起,我.resume()它進行.resume()

我擔心的是,如果進程線程看到count==0 ,我的工作人員插入並戳,然后我的進程繼續運行if並進入睡眠狀態。 它不會意識到數據庫中有新內容。

我應該如何以沒有比賽條件的方式編寫此內容。

處理線程:

  1. event.Reset
  2. 從數據庫中提取數據
  3. foreach {處理}
  4. 如果count == 0則事件。
  5. 重復

而另一個線程:

  1. 驗證數據
  2. 插入數據庫
  3. event.Set()

您將有額外的喚醒(在空隊列中喚醒,無需處理,再進入睡眠狀態),但不會丟失插入內容。

我認為這可能是您需要的結構。

private readonly Queue<object> _Queue = new Queue<object>();
private readonly object _Lock = new object();

void FillQueue()
{
    while (true)
    {
        var dbData = new { Found = true, Data = new object() };
        if (dbData.Found)
        {
            lock (_Lock)
            {
                _Queue.Enqueue(dbData.Data);
            }
        } 

        // If you have multiple threads filling the queue you
        // probably want to throttle it a little bit so the thread
        // processing the queue won't be throttled.
        // If 1ms is too long consider using 
        // TimeSpan.FromTicks(1000).

        Thread.Sleep(1);
    }       
}

void ProcessQueue()
{
    object data = null;

    while (true)
    {
        lock (_Lock)
        {
            data = _Queue.Count > 0 ? _Queue.Dequeue() : null;
        }

        if (data == null)
        {
            Thread.Sleep(1);
        }
        else
        {
            // Proccess
        }         
    }        
}

暫無
暫無

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

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