Как спроектировать синхронизацию потоков в этом случае - PullRequest
2 голосов
/ 19 января 2012

Мое требование следующее:

  1. Существует процесс с несколькими потоками.
  2. Один из потоков (T1) запускается пользовательским событием
  3. Существует задача, которую необходимо выполнить в отдельном потоке (T2), который должен вызываться T1
  4. Теперь T1 должен проверить, что система еще не выполняет задачу в T2.Если его нет, то он должен вызвать T2 и затем выйти.Если T2 все еще работает, то я должен просто вернуться из T1, зарегистрировав ошибку.Я не хочу держать T1, пока T2 не будет завершен.
  5. T2 обычно занимает много времени.Таким образом, в случае, если T1 запущен до того, как T2 завершил, он должен просто вернуться с ошибкой.
  6. Намерение ни при каких обстоятельствах не должно быть двух потоков T2

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

Mutex  g_mutex;
Semaphore  g_semaphone;

T1:

if TryLock(g_mutex) succeeds // this means T2 is not active.
spawn T2
else  // This means T2 is currently doing something
return with an error.
wait (g_sempahore) // I come here only if I have spawned the thread. now i wait for T2 to pick the task
// I am here means T2 has picked the task, and I can exit.

T2:

Lock(g_mutex)
signal(g_semaphore)
Do the long task
Unlock(g_mutex)

И это прекрасно работает.Но я хочу знать, есть ли более простой способ сделать это.

1 Ответ

0 голосов
/ 19 января 2012

Не используйте мьютекс, подобный этому.Замки Mutex должны храниться в течение минимально необходимого времени.В этом случае есть логический флаг t2_running, который защищен мьютексом.В T1 выполните:

  1. lock g_mutex
  2. Read t2_running
  3. Если установлен t2_running, разблокируйте g_mutex и выйдите с ошибкой
  4. Set t2_running
  5. Unlock g_mutex
  6. Заполнение данных для T2
  7. Spawn T2
  8. Ожидание g_semaphore
  9. Выход с успехом

T2 может сделать:

  1. Считать данные
  2. сигнал g_semaphore
  3. Обработатьdata
  4. lock g_mutex
  5. Clear t2_running
  6. Unlock g_mutex
  7. exit
...