Почему не возможен синхронизованный вывод двух потоков при использовании двух мутексов?
=========================================================================================

 Здравствуйте,  
  

Возникла задача - синхронизовать вывод родительской и дочерней нитей ( их всего 2) : сначала родительская нить выводит первую строку, затем дочерняя, затем родительская вторую строку и т.д. Использовать можно только мутексы, остальные средства синхронизации запрещены. Сходу не могу доказать, почему это невозможно. Подскажите, пожалуйста.  
  

Исходный текст задачи:  
  

> Напишите программу, которая создает нить. Используйте атрибуты по умолчанию. Родительская и вновь созданная нити должны распечатать десять строк текста. Модифицируйте программу так, чтобы вывод родительской и дочерней нитей был синхронизован: сначала родительская нить выводила первую строку, затем дочерняя, затем родительская вторую строку и т.д. Используйте мутексы.   
>   
> 
> Явные и неявные передачи управления между нитями (sleep(3C)/usleep(3C), sched\_yield(3RT)) и холостые циклы разрешается использовать только на этапе инициализации.   
>   
> 
> Докажите, что данная задача не может быть решена с использованием двух мутексов без использования других средств синхронизации.

  
  

Заранее благодарен. 

[https://ru.wikipedia.org/wiki/%D0%9C%D1%8C%D1%8E%D...](https://ru.wikipedia.org/wiki/%D0%9C%D1%8C%D1%8E%D1%82%D0%B5%D0%BA%D1%81)  

В каждый конкретный момент только один поток может владеть объектом, защищённым мьютексом 

 А точно нельзя?  

Я бы сделал так…  
  

Поток 1.  

```
мютекс2.войди
поток2.старт
повторяй 10 раз
  мютекс1.войди
  writeln
  мютекс2.выйди
поток2.дождись
мютекс2.выйди
```
  

Поток 2.  

```
повторяй 10 раз
  мютекс2.войди
  writeln
  мютекс1.выйди
```
  

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

Единственное спорное «средство синхронизации» — в потоке 1 дождаться завершения потока 2. 

 Что за чушь? Для этого мьютексы и придумали. Блокируем мьютекс родителем, выводим строчку, устанавливаем некий глобальный ключ в 1, сбрасываем мьютекс, ждем, пока ключ не будет 0. В дочернем же ждем, пока ключ не будет 1, блокируем мьютекс, выводим строчку, сбрасываем ключ, разблокируем мьютекс.  

Если используются не потоки (pthreads), а процессы (fork), то нужно убрать буферизацию или после каждой записи сбрасывать буферы.  
  

См. мой ответ с двумя мьютексами в комментарии к этому ответу. 

 Если вас смущает **простая** переменная (флаг) в ответе Японский Городовой ("Что за чушь?..." - что совершенно справедливо ;-) ), то я вам набросаю другую схему - **каждый** из потоков выполняет что-то подобное:  

```
while( true ) {
   while( pthread_mutex_trylock( &mutex ) == EBUSY );
   cout << "это мя строка, ура!" << endl;
   pthread_mutex_unlock( &mutex ); 
}
```
  

Здесь то и переменных никаких нет кроме мютекса ... - компилируйте, выполняйте, насаждайтесь ;-)