【问题标题】:Calling execv after creating a thread创建线程后调用 execv
【发布时间】:2017-03-10 20:09:28
【问题描述】:

我对线程,进程,execv等非常陌生。我研究过,发现当你执行一个execv时,它会占用调用进程的空间。我想知道当你在 main 中创建一个线程,然后在线程之后直接调用 execv 时会发生什么(不是在它完成之前,而是在创建线程之后)。我知道 execv 将替换 main 但这是否意味着它也将替换线程或者线程能够像正常一样执行和完成?

我要问的小例子:

  int main(){
      printf("hello from main!);
      char *buffer = "some data";

    if(pthread_creat(&mythreadpid, NULL, thread1, buffer){
        printf("ERROR!!");
     }

     execv(...) //do execv here

}

void *thread1(void *buffer){
  printf("calling from my thread!");

 //do something else

}

我已经对此进行了测试,但我确实遇到了奇怪的行为,因为我的线程无法完成,所以我想知道这是否是它的原因

【问题讨论】:

  • execv 替换整个进程,而不仅仅是一个线程。
  • 所以它将替换我从 main AND main 创建的线程?
  • 是的,当前进程的所有内存和状态都被exec覆盖了,除了环境和打开的文件描述符。
  • 好的,如果我要创建一个进程而不是线程,或者新进程不会被替换,这会是一样的吗?
  • 子进程狂野地执行新代码而不是他的父进程。在 C 中使用 fork()

标签: c process pthreads execv


【解决方案1】:

所有exec 函数将整个进程替换为正在执行的程序。所有线程都被销毁。

如果你想在不影响当前进程的情况下执行另一个程序,你应该先使用fork()创建一个新进程,然后在子进程中调用execv()。有关在多线程程序中使用 fork() 时需要注意的一些注意事项,请参阅 Is it safe to fork from within a thread?

【讨论】:

  • 在 exec 中维护的状态不仅仅是环境和打开的文件描述符:例如。当前工作目录;忽略信号和信号掩码的处理;掩码; ptrace 状态...
  • @caf 谢谢,我感觉我遗漏了一些细节。我刚刚删除了它,因为它对这个问题并不重要。
  • @caf,正如我在对该问题的另一条评论中所说的那样,在对exec*(2) 的调用中指定了环境,因此它也被替换了。环境保存在进程的虚拟空间中,唯一保留的东西是诸如开放描述符之类的资源,这些资源不存储在进程虚拟地址空间中。不要求新环境的调用,只需使用收到的环境作为新的exec*(2) 调用的参数。仅保留没有 O_CLOEXEC 标志的打开描述符。拥有它的将被关闭。您还会丢失所有 mmap(2)ed 段。
  • @LuisColorado 环境仅在execveexecle 中指定。但所有这些都与我的回答无关,这就是为什么我不提任何保留的内容。
  • @Barmar,我只是说环境映射在进程的虚拟空间上,因此无法保留。没有 unix 将环境保存在系统位置,因为访问它需要系统调用。其他 execl(2)execv(2) 及其路径对应项从 environ 全局变量中获取环境。事实上,你可以通过NULL,然后你根本就没有环境。
猜你喜欢
  • 1970-01-01
  • 2015-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-29
  • 1970-01-01
  • 1970-01-01
  • 2012-01-22
相关资源
最近更新 更多