使用pthreads计算多个网页中锚标记的数量

时间:2016-10-14 15:38:12

标签: c multithreading parsing pthreads

我目前正在进行涉及线程的任务,而且我不是专业的程序员,所以我正在学习如何使用线程。我的任务是计算一个网页中锚标记的数量,我得到一个包含100个网址的txt文件,我减少到五个网址,以便我可以测试它,目标是返回每个网址上找到的锚标记数量。

我的问题是当我运行我的代码而没有我的for循环它工作正常,但使用for循环它不会调用线程中的函数。

我想要做的是使用for循环,因为我将循环100个URL。

void runThreads(int num_urls){

pthread_t threads[100];

for ( x=0; x<num_urls-1; x++ ) 
{

     pthread_create(&threads[x], NULL,(void *) th_run,(void *) &x);

}

使用for循环时输出错误...只有最后一个线程才真正起作用。 th_run接受一个int * i,EXP:void th_run(int * i)。我怎样才能解决这种竞争状况?

URL=www.google.com
CNT=0
FD=-1
URL=www.facebook.com
CNT=0
FD=-1
URL=www.youtube.com
CNT=9
FD=3

3 个答案:

答案 0 :(得分:0)

所有主题都获得相同的参数&t。当第一个线程有机会运行时,循环就完成了,它指向的值,即t的值,是num_urls,所以所有线程都运行相同的参数

编辑:最直接的修复方法是传递不是索引(线程真的不关心),而是线程应该处理的数据地址:

    pthread_create(&threads[t], NULL,(void *) th_run, &web_array[t]);

它看起来像是一个越界访问。通常情况下,web_array[num_urls]不应该有效,但如果没有看到read_url_file代码(它有while (!feof())循环,那么很难说肯定,不是吗?)。

答案 1 :(得分:0)

在创建任何线程之前,您需要为每个线程创建一个数据数据结构数组,并将您希望该线程处理的条目的地址传入该线程。

struct ThreadData {
    vector<string> urls;
    int anchors_found = 0;
};
vector<ThreadData> thread_data(num_threads);
// populate the urls member of each 

for (int x = 0; x < num_threads; ++x) {
    pthread_create(&threads[x], NULL,(void *) th_run,(void *) & thread_data[x]);
}

这样,数据在创建线程时是稳定的,您不必担心线程是否在创建下一个线程之前开始运行。

然后,在您加入所有线程之后,您可以轻松地总结所有线程的结果。

答案 2 :(得分:0)

我找到了解决方案。 声明了一个新的int数组,在我的for循环中,我将index x的值保存到这个数组中,最后在创建线程时使用了数组中的值。