C # Многопоточность - PullRequest
       4

C # Многопоточность

2 голосов
/ 25 сентября 2010

Хорошо.Я хочу, чтобы два потока работали.Текущий код:

    public void foo()
    {      
            lock(this)
            {
                while (stopThreads == false)
                {
                   foreach (var acc in myList)
                   {
                     // process some stuff
                   }
                 }
             }
     }

    public void bar()
    {      
            lock(this)
            {
                while (stopThreads == false)
                {
                   foreach (var acc in myList)
                   {
                     // process some stuff
                   }
                 }
             }
     }

Оба имеют доступ к одному и тому же списку, проблема в том, что первый поток "foo" не снимает блокировку, я думаю;потому что "бар" начинается только тогда, когда "Фу" сделано.Спасибо

Ответы [ 3 ]

3 голосов
/ 25 сентября 2010

Да, так работает замок.

Ключевое слово lock помечает блок операторов как критический раздел, получая взаимное исключение блокировку для данного объекта, выполняя оператор и затем снимая блокировку.

Взаимное исключение означает, что в любой момент может быть не более одного потока, который удерживает блокировку.

Заниматься этим - плохая идея и не рекомендуется. Вы должны создать приватный объект и заблокировать его. Чтобы решить вашу проблему, вы можете заблокировать два разных объекта.

private object lockObject1 = new object();
private object lockObject2 = new object();

public void foo()
{      
    lock (lockObject1)
    {
         // ...
    }
}

public void bar()
{      
    lock (lockObject2)
    {
         // ...
    }
}

В качестве альтернативы вы можете повторно использовать тот же замок, но переместить его в цикл так, чтобы у каждого цикла был шанс продолжить:

while (stopThreads == false)
{
   foreach (var acc in myList)
   {
       lock (lockObject)
       {
           // process some stuff
       }
   }
}

Однако я бы посоветовал вам потратить некоторое время, чтобы понять, что происходит, вместо того, чтобы переупорядочивать строки кода, пока он не будет работать на вашем компьютере. Написание правильного многопоточного кода затруднено.

Для остановки потока я бы порекомендовал эту статью:

1 голос
/ 25 сентября 2010

Поскольку вы на самом деле не задаете вопрос, я предлагаю вам прочитать учебник о том, как работает многопоточность.Специфическое руководство .Net можно найти здесь .В нем представлены темы «Начало работы», «Базовая синхронизация», «Использование потоков», «Расширенные потоки» и «Параллельное программирование».

Кроме того, вы блокируете «this». Msdn говорит:

В общем, избегайте блокировки на общедоступный тип или экземпляры, не зависящие от вашего кода.Общие конструкции lock (this), lock (typeof (MyType)) и lock ("myLock") нарушают это правило:

  • lock (this) является проблемой, если к экземпляру можно получить открытый доступ.

  • lock (typeof (MyType)) - проблема, если MyType общедоступен.

  • lock(“myLock”) - проблема, потому что любой другой код в процессе, использующий ту же строку,поделится тем же замком.

Рекомендуется определять закрытый объект для блокировки или переменную закрытого статического объекта для защиты данных, общих для всех экземпляров.

0 голосов
/ 25 сентября 2010

Проблема в том, что вы работаете с очень грубой блокировкой. Как Foo, так и Bad в основном не работают одновременно, потому что тот, кто запускает первый, останавливает другого на полный цикл работы.

Тем не менее, он должен блокировать ТОЛЬКО, пока он не заберет что-то из списка. Foreach здесь не работает - по определению. Вы должны создать второй список, и каждый поток удаляет верхний элемент (пока он заблокирован), а затем работает над ним.

В основном:

  • Foreach не работает, так как оба потока будут проходить через полный список
  • Во-вторых, замки должны быть гранулированными, так как они блокируются только при необходимости.

В вашем случае блокировка в foo будет снята только после завершения foo.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...