我目前正在进行涉及线程的任务,而且我不是专业的程序员,所以我正在学习如何使用线程。我的任务是计算一个网页中锚标记的数量,我得到一个包含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
答案 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的值保存到这个数组中,最后在创建线程时使用了数组中的值。