LINUX.ORG.RU

help. C.

 


0

4

Доброго времени суток.

Как сделать так, чтобы мьютекс запирал тот поток, которые раньше всех выполнил pthread_mutex_init, т.е. как избежать гонки и упорядочить блокировку мьютекса разными потоками?



Последнее исправление: cetjs2 (всего исправлений: 4)
Ответ на: комментарий от i-rinat

Так это вроде для того, чтобы ключ создался один раз, к мьютексам это отношения не имеет вроде

momo
() автор топика

тот поток, которые раньше всех выполнил pthread_mutex_init

А вы таки один и тот же мьютекс из разных потоков инициализируете?

yoghurt ★★★★★
()
Ответ на: комментарий от yoghurt

Если же вопрос о том, в какой последовательности будут разблокироваться спящие на мьютексе потоки после его освобождения, насколько я помню, этот порядок не определён - т.е. не гарантируется, что потоки проснутся на мьютексе в том порядке, в котором заснули, если их там больше 1. Опять же, насколько я помню, когда-то это гарантировалось, но потом от этого отказались.

А зачем это может быть нужно?

yoghurt ★★★★★
()
Ответ на: комментарий от yoghurt

Ну в ситуации, когда 2 потока(или более) выполнили pthread_mutex_lock на уже заблокированный мьютекс как только блокировка будет снята контроль получит тот поток, которые успеет заблокировать первым, не факт, что это будет тот, которые раньше выполнил pthread_mutex_lock, разве не так?

momo
() автор топика
Ответ на: комментарий от yoghurt

PTHREAD_PRIO_INHERIT в pthread_mutexattr_setprotocol вполне может помочь разрулить доступ к мьютексу по приоритетам. Насколько помню делаем для потоков SCHED_FIFO, ставим приоритеты, для мьютекса выставляем PTHREAD_PRIO_INHERIT и вуаля - лочить мьютекс потоки будут по приоритетам.Хотя я могу и ошибаться - подобной черной магией я давно уже не занимался.

NegatiV
()
Ответ на: комментарий от momo

pthread_once() нужна для того, чтобы выполнить функцию один раз. К изначальному вопросу про pthread_mutex_init() из нескольких потоков этот ответ вполне подходит.

i-rinat ★★★★★
()
Ответ на: комментарий от yoghurt

Вот и я о том же, что не гарантируется, думал, может есть какие-то стандартные средства, интересно стало.

momo
() автор топика
Ответ на: комментарий от momo

не факт, что это будет тот, которые раньше выполнил pthread_mutex_lock, разве не так?

Почему тебя вообще волнует порядок разблокировки?

i-rinat ★★★★★
()

<тыча пальцем в небо> Возможно ТС хочет изобрести shared/exclusive lock

b-stern
()
Ответ на: комментарий от i-rinat

Хм, кому-то нравится читать весь этот поток брани?

Дело в том, что всё познаётся в сравнении. Люди смотрят на эту исполненную запредельного чсв анскилльную лалку, и сами растут в своих глазах.

Manhunt ★★★★★
()
Последнее исправление: Manhunt (всего исправлений: 1)
Ответ на: комментарий от momo

Стандартных судя по всему нет (кстати, винда до недавних пор как раз так вела себя с блокировками, и та перестала), но можно навелосипедить свой велосипед на атомарных операциях поверх обычного мьютекса.

Другое дело - зачем это нужно? Я не вижу смысла. Возможно, тут уже архитектуру стоит пересмотреть.

yoghurt ★★★★★
()
Ответ на: комментарий от yoghurt

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

momo
() автор топика
Ответ на: комментарий от momo

Тут нет практической цели, просто вдруг стало интересно

Лучше почитай что такое этот самый мутекс и как он работает. сразу такие глупости перестанешь спрашивать.

anonymous
()
Ответ на: комментарий от yoghurt

кстати где он? захерел говорят...

anonymous
()
Ответ на: комментарий от anonymous

А что тут глупого? Мне вот стало интересно, а ответа в литературе не нашел. Если я где-то ляпнул глупость, вразуми, а не просто какашку кинь.

momo
() автор топика
Ответ на: комментарий от momo

Да не за что. Оно правда старое, закрытое и так далее. Но общая идея должна быть ясна.

hateyoufeel ★★★★★
()
Ответ на: комментарий от batbko

Я так понял он хочет чтобы определенный поток захватывал мьютекс с приоритетом перед остальными. По формулировке задачи до конца так и не ясно что же ему было нужно и я предположил что речь об priority inversion.

NegatiV
()
Ответ на: комментарий от NegatiV

Не совсем, я просто хочу чтобы было так: если какой-то потом раньше других выполнил mutex_lock, он должен его и получить, когда мьютекс разблокируется.

momo
() автор топика
Ответ на: комментарий от I-Love-Microsoft

Не знает, как быстро складывать числа.

t184256 ★★★★★
()
Ответ на: комментарий от NegatiV

Уже прочитал про pthread_cond_t, это вроде оно и есть) спасибо

momo
() автор топика
Ответ на: комментарий от NegatiV

А если приоритеты равны у потоков, то они будут поочередно блокировать mutex?

momo
() автор топика
Ответ на: комментарий от NegatiV

mutex-ам я задал в параметре PTHREAD_PRIO_INHERIT, поставил приоритет у всех один и задал SCHED_FIFO. Запускаю 3 потока на 100 сообщений из очереди, так вот 1 из потоков(всегда разный) хватает >90 или около того.

momo
() автор топика
Ответ на: комментарий от NegatiV

B влияет ли изменение приоритета через pthread_setschedparam на гонку между потоками? т.е. если поставить потоку больший приоритет будет ли он выигрывать гонку?

momo
() автор топика
Ответ на: комментарий от NegatiV

pthread_yield и sched_yield оказывают маленький эффект или вообще не оказывают, может есть тонкость какая-то? не подскажешь?

momo
() автор топика
Последнее исправление: momo (всего исправлений: 1)
Ответ на: комментарий от momo

Если треды с одинаковым приоритетом, то планироваться даже с FIFO они будут «случайно» и придется изобретать FIFO mutex. Постараюсь откопать код где уже решалась подобная проблема (интенсивный I/O с высоким приоритетом) - там вроде решилось без велосипедов.

NegatiV
()
Ответ на: комментарий от NegatiV

Сейчас у меня нет цели сделать так, чтобы треды точно доуг за другом шли, мне надо, чтоб они примерно одинаково работали. По идее yield должен помочь, но все равно один поток захватывает управление постоянно. Я штуковину запилил с изменением приоритета потока после захвата сообщения из очереди, следующий поток возвращает предыдущему его приоритет. Но это костыль, ведь yield должен кидать поток в конец очереди потоков одинакового приоритета.

momo
() автор топика
Ответ на: комментарий от NegatiV

Заметил еще одну вещь, если я запускаю программу через valgrind, что pthread_yield работает прекрасно, а поднятие/опускание приоритета не помогает(доходит до того, что 2 из 3х потоков почти не активны), без valgrind все наоборот.

momo
() автор топика
Ответ на: комментарий от momo

Попробуй SCHED_RR - если таски, которые выполняют потоки идентичны, то нагрузка должна равномерно по ним размазаться и без sched_yield().

NegatiV
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.