C ++: синхронизация потоков - PullRequest
1 голос
/ 10 мая 2011

Я пытаюсь синхронизировать два потока (работающих на одной карте C ++), используя библиотеку Boost. Я должен сказать, что я не эксперт в C ++, и я нахожу документацию по надстройке довольно сложной для понимания.

То, чего я хочу достичь, это что-то вроде этого:

#Thread 1
get access to the map
put in something
release access 

#Thread 2
wait until map is empty
when it's not empty anymore, wake up and gain access
perform operations on one entry of the map
leave access to somebody else

Я пытался использовать Mutex и condition_variables, но код не работал должным образом. В частности, когда thread2 просыпался (после ожидания переменной cond.), Он не получал прямого доступа к карте, но был кто-то еще, кто получил доступ и очистил карту. Поэтому я получил ошибку сегментации, потому что ожидал, что карта будет заполнена, пока она была пустой, когда я к ней обращался.

Кроме того, я хотел бы понять разницу между чем-то вроде mymutex.lock() и вызовами типа boost::mutex::scoped_lock scopedLock(mutex_); или unique_lock.

Спасибо за преподавание:)

РЕДАКТИРОВАТЬ: здесь я попытался извлечь соответствующие части моего кода. Поскольку я не очень хорошо понимал, как работает синхронизация, это может не иметь особого смысла ...

//COMMON PART
boost::mutex mutex1;
boost::mutex mutex2;
boost::condition_variable cond;
boost::mutex::scoped_lock mutex2lock(mutex2);

//THREAD 1
...
if(someCondition){
    mutex1.lock();
    map[id]=message;
    cond.notify_one();
    mutex1.unlock();
}
...


//THREAD 2
...
cond.wait(mutex2lock);
mutex.lock();
//Perform operation on map[id]
doSomething(map[id]));
mutex.unlock();
...

Ответы [ 2 ]

2 голосов
/ 10 мая 2011

Кроме того, я хотел бы понять разницу между чем-то вроде mymutex.lock () и такими вызовами, как boost :: mutex :: scoped_lock scopedLock (mutex_);или unique_lock.

Google для "c ++ RAII":

С mymutex.lock() вы «вручную» блокируете мьютекс.(И позже придется разблокировать его «вручную».)

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

1 голос
/ 11 мая 2011
boost::mutex::scoped_lock mutex2lock(mutex2);

Это должно быть, если я правильно понимаю, но большой замок на mutex2, который будет длиться всю длину вашего Mutex.

Скорее всего, вы хотите эту блокировку в контексте второго потока, но я не очень понимаю, почему условие_вариабельная хочет это.

На самом деле, кажется, что условие condition_variable немного неправильное для того, что вы делаете, читая документацию:

Атомный вызов lock.unlock () и блокирование текущего потока. Поток будет разблокирован, когда получит уведомление посредством вызова this-> notify_one () или this-> notify_all (), или spuriously

Это описание мне кажется, что оно может просто разблокировать, когда он чувствует, что может работать (вероятно, в зависимости от времени). Кажется, вам, вероятно, нужно проверить, является ли ваш список действительным, и если нет, снова вызвать wait если вы планируете использовать condition_variable.

...