Как справиться с этим (дБ) состояние гонки очереди? - PullRequest
1 голос
/ 22 января 2010

В основном у меня есть несколько потоков, которые добавляют данные в очередь через SQLite.У меня есть еще один поток, который тянет их и обрабатывает их по одному (слишком много ресурсов, чтобы сделать несколько одновременно).Поток обработки делает это:

  1. извлечение данных из БД
  2. foreach {процесс}
  3. , если число == 0 {thread.suspend ()} (пробуждаетсяthread.resume ())
  4. повтор

мой рабочий поток выполняет:

  1. Проверка данных
  2. Вставка в БД
  3. вызов Queue.Poke (QueueName)

Когда я нажимаю на него, если поток приостанавливается, я .resume() it.

Что меня беспокоит, так это процесснить видит count==0, мой рабочий вставляет и тыкает, тогда мой процесс продолжается вниз, если и спит.Он не поймет, что в БД что-то новое.

Как мне написать это так, чтобы у меня не было состояния гонки.

Ответы [ 2 ]

1 голос
/ 22 января 2010

Обработка нити:

  1. event.Reset
  2. извлечение данных из БД
  3. foreach {процесс}
  4. если count == 0, то событие. Ожидание
  5. повтор

И другой поток:

  1. Подтверждает данные
  2. Вставка в БД

У вас будут дополнительные пробуждения (пробуждение в пустой очереди, ничего не обрабатывать, вернуться в режим сна), но вы не пропустите вставки.

0 голосов
/ 22 января 2010

Я думаю, что это может быть структура, которая вам нужна.

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
        }         
    }        
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...