Напишите программу, которая создает нить. Используйте атрибуты по умолчанию. Родительская и вновь созданная нити должны распечатать десять строк текста. Модифицируйте программу так, чтобы вывод родительской и дочерней нитей был синхронизован: сначала родительская нить выводила первую строку, затем дочерняя, затем родительская вторую строку и т.д. Используйте мутексы.
Явные и неявные передачи управления между нитями (sleep(3C)/usleep(3C), sched_yield(3RT)) и холостые циклы разрешается использовать только на этапе инициализации.
Докажите, что данная задача не может быть решена с использованием двух мутексов без использования других средств синхронизации.
в котором будет указатель на мьютекс текущего потока, и на мьютекс другого потока.
мютекс2.войди
поток2.старт
повторяй 10 раз
мютекс1.войди
writeln
мютекс2.выйди
поток2.дождись
мютекс2.выйди
повторяй 10 раз
мютекс2.войди
writeln
мютекс1.выйди
остальные средства синхронизации запрещены
на сколько я знаю,
глобальная переменная-флаг является средством синхронизации
#include <stdio.h>
#include <pthread.h>
pthread_mutex_t writer = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t queue = PTHREAD_MUTEX_INITIALIZER;
int global_ctr = 0;
static void *child(void *arg){
while(global_ctr < 10){
if(!pthread_mutex_trylock(&writer)){
if(pthread_mutex_trylock(&queue)){
printf("Child wrote this string\n");
++global_ctr;
}
pthread_mutex_unlock(&queue);
pthread_mutex_unlock(&writer);
}
}
return NULL;
}
int main(){
pthread_t thread;
pthread_create(&thread, NULL, child, NULL);
while(global_ctr < 10){
if(!pthread_mutex_trylock(&writer)){
if(!pthread_mutex_trylock(&queue)){
printf("Parent wrote this string\n");
++global_ctr;
}
pthread_mutex_unlock(&writer);
}
}
return 0;
}
gcc 1.c -lpthread && ./a.out
Parent wrote this string
Child wrote this string
Parent wrote this string
Child wrote this string
Parent wrote this string
Child wrote this string
Parent wrote this string
Child wrote this string
Parent wrote this string
Child wrote this string
Parent wrote this string
Все, довольны?
холостые циклы разрешается использовать только на этапе инициализации.
while(global_ctr < 10){
if(!pthread_mutex_trylock(&writer)){
}
}
В задаче нужно что-то передавать. Без циклов это сделать невозможно.
#include <pthread.h>
#include <iostream>
using namespace std;
pthread_mutex_t mux1 = PTHREAD_MUTEX_INITIALIZER,
mux2 = PTHREAD_MUTEX_INITIALIZER;
void* tfunc ( void* parm ) {
int rep = (int)parm;
for( int i = 0; i < rep; i++ ) {
pthread_mutex_lock( &mux2 );
cout << "child: строка №" << i + 1 << endl;
pthread_mutex_unlock( &mux1 );
}
return NULL;
};
int main( int argc, char *argv[] ) {
pthread_mutex_lock( &mux2 );
pthread_t tid;
const int rep = 5;
pthread_create( &tid, NULL, tfunc, (void*)rep );
for( int i = 0; i < rep; i++ ) {
pthread_mutex_lock( &mux1 );
cout << "parent: строка №" << i + 1 << endl;
pthread_mutex_unlock( &mux2 );
}
pthread_join( tid, NULL );
};
$ ./2thr
parent: строка №1
child: строка №1
parent: строка №2
child: строка №2
parent: строка №3
child: строка №3
parent: строка №4
child: строка №4
parent: строка №5
child: строка №5
только чередование блокированных состояний.
однако в С++ данный код был бы не корректен
using namespace std;
mutex mux1, mux2;
void tfunc( int rep ) {
for( int i = 0; i < rep; i++ ) {
mux2.lock();
cout << "child: строка №" << i + 1 << endl;
mux1.unlock();
}
};
int main( int argc, char *argv[] ) {
mux2.lock();
const int rep = 5;
thread thr( tfunc, rep );
for( int i = 0; i < rep; i++ ) {
mux1.lock();
cout << "parent: строка №" << i + 1 << endl;
mux2.unlock();
}
thr.join();
};
Откуда вы можете быть уверены, что под всеми нужными вам системами потоки будут реализованы только так
под Windows ваш код вызывает сбой программы из-за одновременной попытки писать в консоль из двух потоков.
примите во внимание, что на pthread этот код тоже не корректен (почему - я писал в ответе к Олегу).
вместо следования стандарту.
ваш код может быть выполнен неправильно, если после первой итерации в главном потоке итерация во втором выполнится дважды (строка из второго потока будет выведена 2 раза).
Впрочем, я не читал стандарта POSIX и не могу утверждать, что он везде корректен, однако мне слабо верится, что там есть прямо противоположные утверждения.
2)
Я написал "то стандарту POSIX, которому следует версия целевой ОС".
Ну, вы, блин, даёте.
while( true ) {
while( pthread_mutex_trylock( &mutex ) == EBUSY );
cout << "это мя строка, ура!" << endl;
pthread_mutex_unlock( &mutex );
}