2011-05-20 112 views
1

我正在用C编写一个程序来计算某些网站的访问时间。 sitenames存储在urls数组的每个元素中。如果我取出for(y = 0; y <迭代; y ++)循环,那么一切运行良好。但如果我保留它。第一个网站urls [0]在第二个for循环完全结束并递增后变得混乱yfor循环中的线程

这是什么原因造成的?

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, &bgn); 
     rc = pthread_create(&threads[j], NULL, wget, (void *) &thread_args[j]); 
     rc = pthread_join(threads[j], NULL); 
     clock_gettime(CLOCK_REALTIME, &nd); 
     times[j] = timediff(bgn,nd); 
    } 
} 
+0

你为什么要创建一个线程,然后马上加入呢?这是浪费,可能会减慢你的时间。 – WirthLuce 2011-05-20 01:44:41

+2

不只是浪费,它使线程完全没有意义。你可以用'wget(&thread_args [j]);' – 2011-05-20 02:24:00

+0

来代替'pthread_create'和'pthread_join';从吞吐量的角度来看,在一个循环中执行创建以及在一个循环中执行连接会更有意义第二个循环。然后再次,你不需要线程来并行产生一堆子进程 - 在一个循环中''fork()'/'exec()'然后'wait()'让它们退出。 – bk1e 2011-05-20 03:24:28

回答

5

一些可能性...

str1出现的所有线程之间共享。这是在那里发生麻烦的秘诀。

str1只有20个字符长。很难相信包括URL在内的整个wget命令行将少于20个字符。所以你写下str1的结尾。

考虑制定str1一个局部变量wget(),并且无论是使其基础上,长度大小的字符数组大到足以应付你可能有尽可能大的wget命令行,或者动态分配,并释放它内wget()命令行常量部分和当前URL。

+0

^对于第一个,是的,但我调用了一个pthread_join()来等待每个线程完成,因此不会有与str1的资源冲突,对吧? – John 2011-05-20 01:41:45

3

我敢打赌,urls + wget字符串中的一个字符串长于20个字节,正在覆盖该数据。使str1变大,并将其移动到您的wget函数中(多个线程不应写入未锁定的共享资源)。

+0

谢谢你们,str1是个问题。我把它改成了str1 [200],它没有用完房间! – John 2011-05-20 01:55:47