正如您可能知道的那样,应用程序中的所有线程都在分叉进程中死亡,而不是执行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位的相比,它会有什么额外的困难?
答案 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。所以也许这是你的选择。