在fork之后重新创build死线程

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

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

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

另外请注意,我正在使用64位体系结构。 与32位相比,还有什么额外的困难呢?

我看到了两种可能的方式,在脚下拍自己的头发,然后丢掉头发:W W W W W W W W W W W W W wtry to do this:

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

当前进程中的其他线程不会被分叉处理 – 它们仍然存在并在父进程中运行。 您似乎遇到的问题是fork只在当前过程中分叉单个线程,创建一个运行一个线程的新进程,并在父进程中具有所有非线程资源的副本。

你显然想要的是一种复制整个多线程任务的方法,把所有的线程分成几个线程并创建一个新的进程/任务。

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

不幸的是,POSIX的pthread接口是绝望的,并没有提供这种方式。 特别是,它没有任何反射接口,让你找出哪些线程正在运行。

如果你想尽量做到这一点,我可以看到两种方法试图解决这个问题:

  • 在/ proc / self / task中找出你的进程中正在运行的线程,以非常便携的方式有效地获得反射接口。 你可能最终必须跟踪(2)其他线程才能获得内部状态。 这将是非常困难的。

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

第二个选项比较容易(也有点可移植性),但是只有当你有权访问整个应用程序的所有源代码,并且可以修改它以正确使用你的包装器的时候,它才会起作用。

只是搜索一下我发现solaris有一个forkall()调用,正是你想要的,看到这里的文档:

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

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