#c #multithreading #pthreads #pthread-join
#c #многопоточность #pthreads #pthread-join
Вопрос:
Я пытаюсь написать многопоточную программу и сталкиваюсь с некоторыми проблемами.
После того, как я запустил main.c
, и я получаю
i: 0
новый поток 0
новый поток 1
i: 1
i: 1
//main.c
#include <pthread.h>
#include <stdio.h>
#include <stdint.h>
void* routine(void* arg)
{
int id = (intptr_t) arg;
printf("new thread %dn", id);
pthread_exit((void*)(intptr_t) id);
}
int main()
{
pthread_t t[2];
int i;
for(i=0; i<2; i )
{
int ret = pthread_create (amp;t[i], NULL, amp;routine, (void *)(intptr_t) i);
if(ret != 0) {
printf("Error: pthread_create() failedn");
return -1;
}
}
int id;
/////////here
for(i=0; i<2; i )
{
printf("i: %dn",i);
pthread_join(t[i], (void **)amp;id);
}
/////////here
pthread_exit(NULL);
}
Мои проблемы
- Почему последний цикл выполняется трижды?
- Если я дважды изменяю
pthread_t t[2]
pthread_t t
и создаю, можно ли дважды вызвать pthread_join ?
Спасибо, что уделили время чтению моего вопроса.
Комментарии:
2. Что касается второго вопроса: Нет. Второй вызов
pthread_create
перезапишетpthread_t
переменную.3. @JoachimPileborg Я понял!! Спасибо @GillBates Версия моего компилятора
gcc (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4
, которая не работает правильно. Это проблема в зависимости от случая?4. » это выполняется неправильно». в основном это никогда не ошибка в компиляторе.
5. @GillBates: Просто не повезло, похоже, что это сработало.
Ответ №1:
Сначала добавьте еще несколько отладочных журналов:
int id;
for(i=0; i<2; i )
{
printf("i: %dn",i);
pthread_join(t[i], (void **)amp;id);
printf("id[%d]: %dn", i, id);
}
Повторно запустите и запомните результат.
Затем измените его, чтобы он выглядел следующим образом
int id;
for(i=0; i<2; i )
{
void * pv;
printf("i: %dn",i);
pthread_join(t[i], amp;pv); /* Add error checking here! */
id = (intptr_t) pv;
printf("id: %dn", id);
}
Повторно запустите и сравните с предыдущей версией.
Как правило,:
Если вы сталкиваетесь с кажущейся необходимостью приведения в C (не C ), всегда подумайте дважды, так как есть только очень, очень, очень редкие случаи, когда приведение в C необходимо, а не просто скрывает ошибку программирования, отключая компилятор.
Комментарии:
1. Я все еще думаю, что это немного странно при
i
изменении на 0 после вызоваpthread_join
в моем случае. Я не переходилi
к этой функции. Но в любом случае, спасибо за ваш ответ и предложения.2. @ShawnHuang:
pthread_join()
ожидает, что avoid**
, адрес указателя, он отменит ссылку на него, чтобы стать avoid*
, а затем присваивает этомуvoid*
значению указателя, которое, вероятно, равно 8 байтам, память, на которую ссылается то, что вы передали, является anint
, ее ширина составляет всего 4 байта. Таким образом, некоторые другие 4 байта перезаписываются. Эти 4 байта, скорее всего, принадлежатi
.3. Я никогда не учитывал этот побочный эффект при кастинге. Еще раз спасибо за вашу помощь.