семафоры C # Метод синхронизации объектов был вызван из несинхронизированного блока кода - PullRequest
1 голос
/ 09 ноября 2019

Я пытался следовать фрагменту псевдокода, имеющему отношение к семафорам, и когда я перевел код на C #, я получаю ошибку в названии.

После некоторого исследования происходит ошибка, потому что я звоню cust_ready.ReleaseMutex() без вызова cust_ready.WaitOne() в том же потоке. Проблема в том, что это именно то, что делает псевдокод, поэтому я не уверен, как решить эту проблему? Вызывается

cust_ready.WaitOne(), но в отдельном потоке ниже приведен псевдокод:

Thread1:

wait (mutex2);

enqueue (custnr);

сигнал (cust_ready);

сигнал (mutex2);

Thread2:

wait (cust_ready);

wait (mutex2);

dequeuel (b_cust);

сигнал (mutex2);

и это мой код C #:

Thread1:

mutex2.WaitOne ();

customerQueue.Enqueue (custnr);

cust_ready.ReleaseMutex ();

mutex2.ReleaseMutex ();

Thread2:

cust_ready.WaitOne ();

mutex2.WaitOne ();

var существует = customerQueue.TryDequeue (out var b_cust);

mutex2.ReleaseMutex ();

Ответы [ 2 ]

1 голос
/ 09 ноября 2019

Mutex - это объект для синхронизации доступа к ресурсам, и вы используете его для защиты customerQueue. С другой стороны, мьютекс не предназначен для передачи сигналов. Для подачи сигнала вы можете использовать AutoResetEvent как cust_ready.

Thread1

mutex2.WaitOne();
customerQueue.Enqueue(custnr);
cust_ready.Set();
mutex2.ReleaseMutex();

Thread2

cust_ready.WaitOne();
mutex2.WaitOne();
var exists = customerQueue.TryDequeue(out var b_cust);
mutex2.ReleaseMutex();

Подобная тема Основы сигнализации потоков

Документация AutoResetEvent - в разделе замечаний упоминаются другие объекты, которые можно использовать для передачи сигналов между потоками.

0 голосов
/ 09 ноября 2019

Я бы рекомендовал использовать ConcurrentQueue Class .

Все открытые и защищенные члены ConcurrentQueue являются поточно-ориентированными и могут использоваться одновременно из нескольких потоков.

...