Вчера полдня бился, так и не разгадал загадку pthreads.
Итак, у меня есть основной поток, который проверяет, не было ли запроса на создание окна GLUT и опрашивает события окон посредством glutMainLoopEvent(). Все бы хорошо, но чтобы другие потоки (которые могут изменять содержимое отображаемого изображения) имели возможность вклиниться между блокировкой/разблокировкой мьютекса, я вставляю паузу в 10мс. И вот в этой паузе и кроется проблема: при убивании этого основного потока с помощью pthread_cancel(GLUTthread) и последующем ожидании смерти (pthread_join(GLUTthread, NULL)) на pthread_join нет-нет, да происходит зависание. Я так понял, что pthread_cancel просто не срабатывает, если вызывается, когда поток находится в состоянии паузы.
Паузу реализовывал тремя способами. Сначала было просто
usleep(10000);
Потом сделал так:
struct timeval tv;
... 
tv.tv_sec = 0;
tv.tv_usec = 10000;
select(0, NULL, NULL, NULL, &tv);
pthread_cond_t fakeCond = PTHREAD_COND_INITIALIZER;
struct timespec timeToWait;
struct timeval now;
while(1){
	pthread_mutex_lock(&winini_mutex);
... // критическая секция
	gettimeofday(&now,NULL);
	timeToWait.tv_sec = now.tv_sec;
	timeToWait.tv_nsec = now.tv_usec * 1000UL + 10000000UL;
	pthread_cond_timedwait(&fakeCond, &winini_mutex, &timeToWait);
	pthread_mutex_unlock(&winini_mutex);
... // некритическая секция
}
Как же с этим бороться?
Сейчас у меня пауза при помощи pthread_cond_timedwait, а еще я запихал в критическую секцию проверку
if(!initialized){
	DBG("!initialized");
	pthread_exit(NULL);
}
void clear_GL_context(){
	FNAME();
	if(!initialized) return;
	DBG("lock");
	pthread_mutex_lock(&winini_mutex);
	initialized = 0;
	DBG("locked");
	 // kill main GLUT thread
	pthread_cancel(GLUTthread);
	pthread_mutex_unlock(&winini_mutex);
	forEachWindow(killwindow_v);
	DBG("join");
	pthread_join(GLUTthread, NULL);
	pthread_mutex_unlock(&winini_mutex);
	DBG("main GL thread cancelled");
}
Вот как правильно поступить?



