我遇到克隆功能的问题,因为它在第9次调用后给我一个分段错误。程序运行正常,直到我开始使用9+个线程。
这是我对克隆的呼吁:
void **child_stack = (void **) malloc(SIGSTKSZ);
clone (func,
(child_stack + SIGSTKSZ),
CLONE_VM | CLONE_FILES | CLONE_PARENT_SETTID,
(void *) argsForFunc,
&pid);
我正在使用clone而不是像pthreads那样的任何更高级别的线程库。
如果有帮助,这是我在使用GDB时遇到的错误:
Program received signal SIGSEGV, Segmentation fault.
clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:66
66 movq %rcx,8(%rsi)
Current language: auto; currently asm
答案 0 :(得分:3)
这是我对克隆的呼吁
不要那个。在你纠正指针运算后(由Jay Conrod回答),你的代码会因竞争条件而死亡,因为你没有像glibc预期的那样设置TLS(线程本地存储)。
实际上,如果你使用直接clone
调用,你就不能永远调用新的任何glibc函数(甚至不是你自己在另一个共享库中的函数(1)) “线程”,或者你冒着间歇性(并且极难调试)失败的风险。只需使用pthread_create()
代替。
这是glibc bug,显示了您将遇到的各种问题(请注意,这是不是 glibc问题)。
(1)因为动态符号分辨率要求进入glibc。
答案 1 :(得分:2)
TJD上面的评论让我立刻看到了问题:你的指针算术得到了堆栈的结尾是不正确的。如果将堆栈分配为:
void **child_stack = (void **) malloc(SIGSTKSZ);
然后你计算堆栈的顶部为:
child_stack + SIGSTKSZ
传递给克隆的实际地址为
child_stack + sizeof(void*)*SIGSTKSZ
也许您的意思是child_stack
有char*
类型?根据定义,sizeof(char)
为1,因此可以为您提供正确的结果。