pthread_mutex_unlосk(&Mutex);
cout « «workerl: число равно " << Number « endl;
}
pthread_mutex_lock(&EventMutex) ,-
cout « «Функция workerl в состоянии ожидания. " « endl;
pthread_cond_wait (&Event, &EventMutex) ;
pthread_mutex_unlock(&EventMutex);
return(0);
}
void *worker2 (void *X) {
for(int Count = l;Count < 100;Count++){
pthread_mutex_lock(&Mutex) ;
Number = Number * 2 ;
pthread_mutex_unlock(&Mutex) ;
cout « «worker2: число равно " « Number « endl;
}
pthread_cond_signal (&Event) ;
cout « «Функция worker2 послала сигнал " « endl; return(0);
}
int main(int argc, char *argv[]) {
pthread_mutex_init (&Mutex,NULL) ;
pthread_mutex_init (&EventMutex,NULL) ;
pthread_cond_init (&Event, NULL) ;
pthread_create(&ThreadA, NULL,workerl, NULL);
pthread_create (&ThreadB, NULL, worker2, NULL) ;
//.. .
return (0);
}
В листинге 5.5 поток ThreadA не может завершиться до тех пор, пока не завершится поток ThreadB. Поток ThreadA должен выполнить цикл 10 раз, а ThreadB — 100. Поток ThreadA завершит выполнение своих итераций раньше ThreadB, но будет ожидать до тех пор, пока поток ThreadB не просигналит о своем завершении.
CC- и СФ-отношения синхронизации невозможно реализовать подобным образом. Эти методы используются для синхронизации пор
Объектно-ориентированный подход к синхронизации
Одно из преимуществ объектно-ориентированного программирования состоит в защите, которую обеспечивает инкапсуляция компонентов данных объекта. Инкапсуляция может обеспечить для пользователя объектов «стратегии доступа к объектам и принципы их применения» [ 24 ]. В примерах, представленных в этой главе, за применяемые стратегии доступа вся ответственность возлагалась на пользователя данных. С помощью объектов и инкапсуляции ответственность можно переложить с пользователя данных на сами данные. При таком подходе создаются данные, которые, в отличие от функций, являются безопасными для потоков.
Для реализации такого подхода данные многопоточного приложения (по возможности) необходимо инкапсулировать с помощью С++-конструкций class или struct. Затем инкапсулируйте такие механизмы синхронизации, как семафоры, блокировки для обеспечения чтения-записи и мьютексы событий. Если данные или механизмы синхронизации представляют собой объекты, создайте для них интерфейсный класс. Наконец, объедините объект данных с объектами синхронизации посредством наследования или композиции, чтобы создать объекты данных, которые будут безопасны для потоков. Этот подход подробно рассматривается в главе 11.
Резюме
Для координации порядка выполнения процессов и потоков