while(1)
{
char buf[800] ={0};
ret=fgets(buf, sizeof(buf) -1, fp);
if(!ret){
...lseek to head of file
continue;
}
//问题很可能出在这里,改成strtok_r还是会同样出错
char *url=strtok(buf,"\n");
index++;
thread=&stk_threads[index];
stk_thread_push_task(thread, url);
if(++index==max_thread)
{
index=0;
}
}
先贴代码如上,问题如下
程序在对一个文件遍历一段时间(我确定还没遇到过尾部)之后,在push到选定thread的队列时【主程序会用strlen判断url处(来源指针)的字串长度,从而拷贝一份出来,防止各线程读到重复的url内容】在strlen时候报段错误。
我知道strtok的实现原理,但是不明白这个段错误在这个情形下发生的具体原因是什么呢?【注意,执行strtok和push到选定线程以及调用strlen拷贝源串的都是主线程自己】
大家讲道理2017-04-17 11:36:07
url
points to a global shared memory. Before your thread processes it, the pointers pushed into the queue have been destroyed by the next strtok
call. If these pointers are accessed again, a segfault will occur.
Just use strtok_r
instead.
黄舟2017-04-17 11:36:07
My understanding is: char buf[800]
is allocated on the stack space of the main thread, and after each strtok
, url
points to the address of buf
. So for the child thread, there is here Cross-thread Stack Access.
https://software.intel.com/sites/products/documentation/hpc/inspectorxe/en-us/2011Update/lin/ug_docs/GUID-F0B0D34B-6691-4033-931F-4BBBD1A1F791.htm
strtok_r
To no avail. Try to copy the content of the url in the heap each time, pass it to the child thread, and then delete it.
Of course, a better way is to allocate corresponding memory to the url in the thread data structure.