在fork之后重新创建死线程

时间:2011-10-27 15:42:23

标签: c linux 64-bit x86 fork

正如您可能知道的那样,应用程序中的所有线程都在分叉进程中死亡,而不是执行fork的线程。但是,我计划通过调用 pthread_create 并使用 pthread_attr_setstack 来重新分叉分叉进程中的线程,以便为新创建的线程分配与死线程相同的堆栈。如下所示。

// stackAddr and stacksize taken from the dead thread    
pthread_attr_setstack(&attr, stackAddr, stacksize);
rc = pthread_create(&thread, &attr, threadRoutine, NULL); 

但是,我仍然需要获取CPU寄存器值,例如堆栈指针,基指针,指令指针等,以从同一点重新启动线程。我怎样才能做到这一点?还有什么我需要做才能成功实现我的目标?

另请注意,我使用的是64位架构。与32位的相比,它会有什么额外的困难?

3 个答案:

答案 0 :(得分:3)

我看到两种可能的方式射击自己的脚和失去的头发^ W ^ W ^ W ^ W ^ W ^ W ^ W ^很难做到这一点:

  • 尝试强制每个线程在getcontext()之前调用fork(),然后通过setcontext()恢复每个线程的上下文。可能不会起作用,但你可以尝试一下。
  • 保存ptrace(PTRACE_GETREGS)ptrace(PTRACE_GETFPREGS),然后使用ptrace(PTRACE_SETREGS)ptrace(PTRACE_SETFPREGS)进行恢复。

答案 1 :(得分:2)

当前进程中的其他线程不会被fork杀死 - 它们仍在那里并在父进程中运行。您似乎遇到的问题是fork仅在当前procces中分叉一个SINGLE线程,创建一个运行一个线程的新进程,其中包含父级中所有非线程资源的副本。

您显然想要的是复制整个多线程任务的方法,分配其中的所有线程并创建具有相同线程数的新进程/任务。

为了做到这一点,你需要找到并暂停进程中的所有其他线程,转储它们的当前状态(包括它们持有的所有锁),分叉一个新进程,然后(重新)创建每个进程子进程中的其他线程,重新连接锁状态以在需要时引用新的子线程。

不幸的是,POSIX pthread接口无可置疑,并没有办法做到这一点。特别是,它没有任何反射界面,可以让你找出实际运行的线程。

如果你想尝试这样做,我可以看到两种尝试解决这个问题的方法:

  • 在/ proc / self / task中查找你的进程中正在运行的线程,以高度不可移植的方式有效地获取反射界面。您可能最终必须ptrace(2)其他线程才能获得其内部状态。这将非常困难。

  • 包装pthreads库 - 而不是直接使用库,拦截每个调用并跟踪所有创建的线程/互斥锁/锁,以便在想要fork时获得该信息。只要您不想使用任何使用pthreads的第三方库,这将正常工作

第二个选项更容易(并且有些可移植),但只有在您可以访问整个应用程序的所有源代码时才能正常工作,并且可以对其进行修改以正确使用包装器。

答案 2 :(得分:0)

只是在谷歌上搜索我发现solaris有一个forkall()调用,它完全符合您的要求,请参阅此处的文档:

http://download.oracle.com/docs/cd/E19963-01/html/821-1601/gen-1.html

我假设您在Linux上运行,但可以在x86硬件上运行solaris。所以也许这是你的选择。