#c #multithreading #pthreads #mutex
#c #многопоточность #потоки #мьютекс
Вопрос:
Я видел эту ошибку, которую, похоже, не могу расшифровать, которая потенциально может быть связана с мьютексом pthread.
То, что я делаю, — это создаю FIFO для каждого потока, и как только он создан, я разблокирую соответствующий поток. Для этого я использую threadWakeupIdx
флаг.
Все, кажется, работает так, как ожидалось, когда у меня есть 3 индекса, определенных в WakeUpThreadIdx
ПЕРЕЧИСЛЕНИИ, НО когда у меня есть 4 (т. Е. NUM_ACTIVE_THREADS
= 4), я получаю следующую ошибку, которую я не могу расшифровать…
tpp.c:84: __pthread_tpp_change_priority: Assertion `new_prio == -1 || (new_prio gt;= fifo_min_prio amp;amp; new_prio lt;= fifo_max_prio)' failed. Aborted (core dumped)
// threads.c void *t1(void *args) { // block till the fifo for T1 thread is created pthread_mutex_lock(amp;lock); while(threadWakeupIdx gt;= (T1_IDX 1)) { pthread_cond_wait(amp;cond, amp;lock); } pthread_mutex_unlock(amp;lock); // ... } void *t2(void *args) { // block till the fifo for T2 thread is created pthread_mutex_lock(amp;lock); while(threadWakeupIdx gt;= (T2_IDX 1)) { pthread_cond_wait(amp;cond, amp;lock); } pthread_mutex_unlock(amp;lock); // ... } void *t3(void *args) { // block till the fifo for T3 thread is created pthread_mutex_lock(amp;lock); while(threadWakeupIdx gt;= (T3_IDX 1)) { pthread_cond_wait(amp;cond, amp;lock); } pthread_mutex_unlock(amp;lock); // ... } void *t4(void *args) { // block till the fifo for T4 thread is created pthread_mutex_lock(amp;lock); while(threadWakeupIdx gt;= (T4_IDX 1)) { pthread_cond_wait(amp;cond, amp;lock); } pthread_mutex_unlock(amp;lock); // ... } // main.h typedef enum { T1_INDEX = 0, T2_INDEX, T3_INDEX, T4_INDEX, NUM_ACTIVE_THREADS } WakeUpThreadIdx; typedef struct { char fifoPath[100]; int fd; } FifoInfo; #define FIFO_REF_PATH "/tmp" // main.c int threadWakeupIdx = 0; pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t cond = PTHREAD_COND_INITIALIZER; static const char *threadNameList[NUM_ACTIVE_THREADS] = {T1_FIFO_NAME, T2_FIFO_NAME, T3_FIFO_NAME, T4_FIFO_NAME}; static pthread_t t1Handler; static pthread_t t2Handler; static pthread_t t3Handler; static pthread_t t4Handler; // init fifo for each thread void InitFifo(FifoInfo *fifoList) { char fifoPath[100] = {0}; for (int idx = T1_INDEX; idx lt; NUM_ACTIVE_THREADS; idx ) { strcpy(fifoPath, FIFO_REF_PATH); strcat(fifoPath, threadNameList[idx]); strcpy(fifoList[idx].fifoPath, fifoPath); // create fifo ... // wake up a respective thread once the fifo is init'd pthread_mutex_lock(amp;lock); threadWakeupIdx ; pthread_cond_broadcast(amp;cond); pthread_mutex_unlock(amp;lock); memset(fifoPath, 0, sizeof(fifoPath)); } } int main() { FifoInfo fifoList[NUM_ACTIVE_THREADS] = {0}; InitFifo(fifoList); pthread_create(amp;t1Handler, NULL, t1, lt;argumentgt;); pthread_create(amp;t2Handler, NULL, t2, lt;argumentgt;); pthread_create(amp;t3Handler, NULL, t3, lt;argumentgt;); pthread_create(amp;t4Handler, NULL, t4, lt;argumentgt;); pthread_join(t1Handler, 0); pthread_join(t2Handler, 0); pthread_join(t3Handler, 0); pthread_join(t4Handler, 0); return 0; }
Редактировать:
Пробовал разные вещи и заметил, что если я прокомментирую, скажем pthread_create(amp;t3Handler, NULL, t3, lt;argumentgt;);
, я не вижу ошибки. Возможно, аналогично случаю с 3 WakeUpThreadIdx
индексами ПЕРЕЧИСЛЕНИЯ.
Почему попытка создать/запустить дополнительный поток вызывает эту проблему?
Комментарии:
1. Почему вы не можете создать объекты fifo перед созданием потоков? Вы можете передать fifo в функцию потока в аргументе — тогда вам может понадобиться только одна функция потока. Вы делаете вещи, которых можно избежать, трудными и сложными:(
2. да, я мог бы разобраться в этом, но также хочу выяснить, что на самом деле вызывает эту проблему…
3. Кого волнует,сможете ли вы его спроектировать? Жизнь слишком коротка для слишком сложного кода, особенно при многопоточности. ПОЦЕЛУЙ за победу:)
4. Есть ли какая-либо часть вашего кода, которая пытается изменить приоритет потока (или, возможно, используемая вами библиотека, которая может попробовать это сделать? Ошибка утверждения выглядит так, как будто кто-то пытается переключиться на значение приоритета потока, которое не поддерживается.
5. @MartinJames те, кто находит способы избежать ошибок, даже не понимая основной проблемы, обречены продолжать находить новые условия входа для все еще не решенной проблемы.