#c #for-loop #pthreads
#c #for-цикл #pthreads
Вопрос:
Я пишу программу на C для вычисления времени доступа к определенным веб-сайтам. Имена сайтов хранятся в каждом элементе массива urls. Если я удаляю цикл for (y = 0; y < итерации; y ), тогда все работает нормально. Но если, если я сохраню это. urls [0], первый веб-сайт, запутывается после того, как второй цикл for полностью завершается и увеличивает y
Что является причиной этого?
char *urls[50]; char str1[20];
void *wget(void *argument)
{
int threadid;
threadid = *((int *)argument);
strcpy(str1, "wget -q --spider ");
strcat(str1, urls[threadid]);
system(str1);
}
for (y = 0; y < iterations; y )
{
for (j = 0; j < numthreads; j )
{
thread_args[j] = j;
clock_gettime(CLOCK_REALTIME, amp;bgn);
rc = pthread_create(amp;threads[j], NULL, wget, (void *) amp;thread_args[j]);
rc = pthread_join(threads[j], NULL);
clock_gettime(CLOCK_REALTIME, amp;nd);
times[j] = timediff(bgn,nd);
}
}
Комментарии:
1. почему вы создаете поток, а затем сразу присоединяетесь к нему? Это пустая трата времени и может замедлить ваше время.
2. Не просто трата времени, это делает потоки совершенно бессмысленными. С таким же успехом вы могли бы заменить
pthread_create
иpthread_join
простым вызовомwget(amp;thread_args[j]);
3. С точки зрения пропускной способности было бы более разумно выполнять creates в одном цикле и выполнять joins во втором цикле. Опять же, вам не нужны потоки для параллельного запуска множества дочерних процессов —
fork()
/exec()
в цикле, а затемwait()
для их завершения.
Ответ №1:
Некоторые возможности…
str1
похоже, что они являются общими для всех потоков. Это верный путь к неприятностям прямо здесь.
str1
имеет длину всего 20 символов. Трудно поверить, что во всей wget
командной строке, включая URL, будет меньше 20 символов. Итак, вы списываете конец str1
.
Подумайте о создании str1
локальной переменной в wget()
и либо сделайте ее массивом символов, достаточно большим, чтобы обрабатывать максимально возможную wget
командную строку, которая у вас может быть, либо динамически выделите ее и освободите внутри wget()
с размером, основанным на длине постоянной части командной строки и текущем URL.
Комментарии:
1. ^ Для первого, да, но я вызвал pthread_join(), чтобы дождаться завершения каждого потока, чтобы не было конфликта ресурсов со str1, верно?
Ответ №2:
Могу поспорить, что одна из строк в urls
строка wget длиннее 20 байт и перезаписывает эти данные. Увеличьте str1
размер и переместите его в свою функцию wget (несколько потоков не должны выполнять запись в один общий ресурс без блокировки).
Комментарии:
1. Спасибо, ребята, проблема была в str1. Я изменил его на str1[200], и ему не хватило места!