Из кода не совсем ясно, каково намерение мьютекса destryLock
, тем более что он не инициализируется статическим инициализатором PTHREAD_MUTEX_INITIALIZER
и не инициализируется pthread_mutex_init
.Однако эта функция уничтожается в этой функции tpDestroy
, поэтому любые вызовы pthread_mutex_lock
, скорее всего, приводят к ошибке EINVAL
.
Это, как говорится, основано на том, как выглядит tpDestroy
как будто должен сделать, то есть уничтожить объект пула потоков, созданный с помощью tpCreate
, в этом коде неясно, каково было намерение для логики;следует отметить, что с этим может возникнуть условие взаимоблокировки:
pthread_mutex_lock(&destryLock);
// first time enter to tpDestory with valid thread pool
if ( threadPool->canInsert != 0) {
threadPool->canInsert = 0;
// make sure tpDestroy will ne called only once for thr thread pool
} else {
return; // dead lock since not unlocking after having locked
}
pthread_mutex_unlock(&destryLock);
Это заставляет поверить, что этот код был построен (по крайней мере частично) кем-то, кто не полностью понимал многопоточность,или не совсем понял, как проект должен соответствовать пулу потоков.
Имеет смысл поместить мьютекс destryLock
в саму структуру пула потоков, поскольку функция работает с объектом пула потоков.переданный, а не глобальный.
Я хотел бы знать правильное место для объявления мьютексов, которые используются так же, как они используются здесь.
Этот вопрос немного широк, учитывая ваше понимание примитивов многопоточности и синхронизации, вместо этого я сосредоточусь на , почему вы хотите мьютекс против , где вы хотите.
Мьютекс позволяет блокировать участки кода несколькими потоками, так что только один поток может одновременно получить доступ к коду.Вы делаете это, потому что в многоядерных системах вполне возможно, чтобы несколько потоков одновременно обращались к одним и тем же данным, что приводило к возникновению условий гонки и, следовательно, к неопределенному поведению.
Если вы хотите заблокироватькод из нескольких потоков, тогда , где может стать немного более понятным, так как вы сможете определить, должен ли мьютекс быть глобальным / локальным статическим объектом или он должен быть объектом-членом.
В качестве примера, скажем, у меня есть игра с кучей врагов;Скорее всего, я оставлю множество врагов в каком-то списке.Когда я хочу перебрать список врагов, скажем, для обнаружения столкновений, ИИ или других игровых эффектов, если в моей игре несколько потоков, действующих по списку врагов, я могу захотеть, чтобы мьютекс блокировался по всему списку, пока я выполняю преформунезависимо от логики игры на врагах, поэтому состояние врагов может быть точным для всех потоков.Это, однако, может быть не лучшим вариантом, так как может привести к задержке;вместо этого я мог бы захотеть создать мьютекс для каждого врага и заблокировать только врага, на которого воздействует логика.
Так что это больше о том, какие объекты с изменяемым состоянием вы хотите защитить.
Iнадеюсь, что это может помочь.