Потоки в циклах for

#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], и ему не хватило места!