Уничтожение pthread в ожидании переменной условия - PullRequest
7 голосов
/ 20 августа 2010

У меня есть pthread в ожидании переменной условия, использующей pthread_cond_wait().Он ожидает данных из структуры очереди, заполненной другим потоком.Я хочу уничтожить этот поток, желательно без pthread_kill().

. В Linux и WinPthreads достаточно сделать

pthread_cancel();
pthread_join()

.

Однако в ОСХ зависает на pthread_join() звонке.Есть предложения?

Ответы [ 3 ]

7 голосов
/ 20 августа 2010

pthread_cancel должен пробудить поток, заблокированный в pthread_cond_wait --- это одна из обязательных точек отмены.Если это не работает, значит что-то не так.

Первое, что нужно проверить, это то, что действительно отменено включение в целевом потоке - явно вызовите pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,&oldstate) в целевом потоке, чтобы убедиться.Если это не сработает, то отмена отменяется на вашей платформе, и вам придется прибегнуть к таким альтернативам, как установка флага «пожалуйста, прекратите сейчас» и сигнализация переменной условия.

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

Между прочим, pthread_kill не не уничтожает поток --- он посылает ему сигнал.

7 голосов
/ 27 августа 2010

Есть ли у вас доступ к очереди и управление схемой объектов для объектов в очереди? Если это так, определите тип объекта очереди, который при удалении из очереди дает команду потоку, обрабатывающему элемент, корректно завершить работу.

Теперь, чтобы закрыть эти потоки, просто отправьте несколько этих «завершенных» объектов в HEAD очереди, которая соответствует количеству потоков, обслуживающих очередь, и присоединитесь к резьб.

Это выглядит намного чище, чем "ядерная опция" в pthread_cancel / kill.

0 голосов
/ 20 августа 2010

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

Это потому, что оновозможно, что поток не отвечает на отмену, пока он находится в состоянии ожидания (или вообще не работает).

POSIX.1c-2004 (v6) сообщает:

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

Это означает, что вы должны явно проверить на отмену сpthread_testcancel().

Другой вариант заключается в том, чтобы фактически установить тип отмены потоков на PTHREAD_CANCEL_ASYNCHRONOUS при первом запуске, например:

int junk;
pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, &junk);
std::cout
    << ((junk==PTHREAD_CANCEL_DEFERRED) ? "Was deferred" : "Wasn't")
    << std::endl;

То есть, конечно,при условии, что это проблема.Вы должны быть в состоянии проверить, проверяет ли он вывод этой третьей строки выше.

Отмена - это запрос к целевому потоку, который он может игнорировать, если пожелает, так какпротив гораздо большего зла pthread_kill().Я большой сторонник того, чтобы позволить потокам контролировать их собственные жизни, поскольку я обнаружил, что это неизменно приводит к меньшему количеству проблем параллелизма.

В стороне: Фактически, будучи скупленнымв очень ранних выпусках pthreads, даже до интеграции в DCE, я все еще обнаружил, что просто использую глобальную переменную для каждого потока, указывающую, когда он должен завершиться, наряду с ручными ударами мьютексов или условных переменных, чтобы разбудить потоки,Я думаю, что я должен обновить свои методы (или я хотел бы, если бы я мог видеть явное преимущество).: -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...