Многопоточная программа на Си зависает
От: Sorc17 Россия  
Дата: 10.10.13 18:27
Оценка:
Всем привет.

Я постигаю многопоточное программирование и сегодня уперся в совершенно не понятное мне поведение своей программы. Вот её тестовый вариант: http://pastebin.com/S6bHbXcU скомпилить можно так: gcc -lpthread test.c -o test Почитал маны по pthread_cancel и pthread_mutex_lock и погуглил и всё равно не пойму, почему программа зависает (блокируется в одном из pthread_join навечно), ведь я освобождаю мьютекс после cancel-ов. И совсем уже взрывает мой мозг то, что если я оставляю константу TEST не объявленной, чтобы убрать вывод из потоков, то сколько программу не запускай, она не виснет. А если константу TEST объявить, то программа зависает через раз.

Подскажите пожалуйста, что я делаю не так
Для нас [Thompson, Rob Pike, Robert Griesemer] это было просто исследование. Мы собрались вместе и решили, что ненавидим C++ [смех].
Re: Многопоточная программа на Си зависает
От: ДимДимыч Украина http://klug.org.ua
Дата: 10.10.13 21:08
Оценка:
Здравствуйте, Sorc17, Вы писали:

S>Подскажите пожалуйста, что я делаю не так


pthread_cancel() можно использовать только если до конца понимаешь, как оно работает. Иначе это источник проблем и головной боли.
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
Re: Многопоточная программа на Си зависает
От: andrey.desman  
Дата: 10.10.13 22:10
Оценка:
Здравствуйте, Sorc17, Вы писали:

S>Всем привет.


S>Я постигаю многопоточное программирование и сегодня уперся в совершенно не понятное мне поведение своей программы. Вот её тестовый вариант: http://pastebin.com/S6bHbXcU скомпилить можно так: gcc -lpthread test.c -o test Почитал маны по pthread_cancel и pthread_mutex_lock и погуглил и всё равно не пойму, почему программа зависает (блокируется в одном из pthread_join навечно), ведь я освобождаю мьютекс после cancel-ов. И совсем уже взрывает мой мозг то, что если я оставляю константу TEST не объявленной, чтобы убрать вывод из потоков, то сколько программу не запускай, она не виснет. А если константу TEST объявить, то программа зависает через раз.


S>Подскажите пожалуйста, что я делаю не так


Убери test("got lock") и все должно заработать.

Что происходит:
Создаются три потока, которые тут же вешаются на мютекс локе.
Мэйн отпускает лок при вызове cond_wait (кстати учти, что он может без причины просыпаться, всегда нужно условие / булевская переменная).
Один из потоков захватывает мютекс, сигналит и отпускает лок.
Управление переходит обратно в мэйн, который вызывает cancel для всех потоков.
Мэйн отпускает мютекс.
Мютекс захватывается другим потоком.
Он вызывает write(), который есть cancellation point. Тот самый test("got lock").
Поток останавливается без отпускания мютекса.
Третий поток все еще ждет мютекса.
Мэйн все еще ждет завершения третьего потока. Пичалька.

ДимДимыч очень сильно прав насчет pthread_cancel().
Re[2]: Многопоточная программа на Си зависает
От: Sorc17 Россия  
Дата: 10.10.13 23:28
Оценка:
Здравствуйте, andrey.desman, Вы писали:

AD>Убери test("got lock") и все должно заработать.


AD>Что происходит:

AD>Создаются три потока, которые тут же вешаются на мютекс локе.
AD>Мэйн отпускает лок при вызове cond_wait (кстати учти, что он может без причины просыпаться, всегда нужно условие / булевская переменная).
AD>Один из потоков захватывает мютекс, сигналит и отпускает лок.
AD>Управление переходит обратно в мэйн, который вызывает cancel для всех потоков.
AD>Мэйн отпускает мютекс.
AD>Мютекс захватывается другим потоком.
AD>Он вызывает write(), который есть cancellation point. Тот самый test("got lock").
AD>Поток останавливается без отпускания мютекса.
AD>Третий поток все еще ждет мютекса.
AD>Мэйн все еще ждет завершения третьего потока. Пичалька.

AD>ДимДимыч очень сильно прав насчет pthread_cancel().


Вот я дерево, а ведь и правда! Спасибо, ребят

Даже можно больше сказать, когда тред заканселился во время владения мьютексом, мьютекс стал "abandoned":

Any mutexes that are held by a thread that terminates, are abandoned and are no longer valid. Subsequent calls by other threads that attempt to acquire the abandoned mutex (pthread_mutex_lock() or pthread_mutex_trylock()) fail with an EOWNERTERM error.


Ну и засада этот cancel ...
Для нас [Thompson, Rob Pike, Robert Griesemer] это было просто исследование. Мы собрались вместе и решили, что ненавидим C++ [смех].
Re[3]: Многопоточная программа на Си зависает
От: Dair Россия https://dair.spb.ru
Дата: 11.10.13 18:09
Оценка:
S>Ну и засада этот cancel ...
pthread_cancel не хочешь ты.
http://stackoverflow.com/questions/4760687/cancelling-a-thread-using-pthread-cancel-good-practice-or-bad
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.