Вызов execv после создания потока

Я очень новичок в потоках, процессах, 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

}

Я проверил это, и у меня было странное поведение, так как мой поток не завершался, поэтому я хочу знать, является ли это причиной.


person unconditionalcoder    schedule 28.10.2016    source источник
comment
execv заменяет весь процесс, а не только один поток.   -  person Barmar    schedule 28.10.2016
comment
так что он заменит мой поток, созданный из основного И основного?   -  person unconditionalcoder    schedule 28.10.2016
comment
Да, exec перезаписывает всю память и состояние текущего процесса, кроме среды и дескрипторов открытых файлов.   -  person Barmar    schedule 28.10.2016
comment
хорошо, будет ли это то же самое, если я создам процесс вместо потока, или этот новый процесс не будет заменен?   -  person unconditionalcoder    schedule 28.10.2016
comment
дикий дочерний процесс выполняет новый код, но не его родителя. использовать fork() в C   -  person Stargateur    schedule 28.10.2016
comment
@Barmar, среда также указывается в execv и по этой причине также заменяется (вызовы, которые ее не указывают, берут ее из полученной среды), как параметры argc и argv на main(). Дескрипторы открытых файлов, не имеющие O_CLOEXEC, также сохраняются, но другие закрываются при системном вызове exec*(2).   -  person Luis Colorado    schedule 03.11.2016
comment
@LuisColorado Я не думал, что мне нужно помещать полное описание exec в свой однострочный комментарий. Как указал caf в своем комментарии к моему ответу, exec сохранил много других вещей, поэтому я убрал детали из своего ответа.   -  person Barmar    schedule 03.11.2016
comment
@Barmar, я полностью с вами согласен, но я бы никогда не поставил среду на первое место среди ресурсов, сохраняемых при вызове exec*(2), потому что она всегда заменяется той, которая передается системному вызову. И причина та, которую я использовал, и я также пишу свои комментарии, чтобы проиллюстрировать вещи.   -  person Luis Colorado    schedule 03.11.2016


Ответы (1)


Все функции exec заменяют весь процесс выполняемой программой. Все темы уничтожены.

Если вы хотите выполнить другую программу, не затрагивая текущий процесс, вы должны сначала использовать fork() для создания нового процесса, а затем вызвать execv() в дочернем процессе. См. раздел Безопасно ли разветвление из потока? для некоторых предостережений, о которых следует знать при использовании fork() в многопоточной программе.

person Barmar    schedule 28.10.2016
comment
В exec поддерживается гораздо больше состояний, чем просто среда и дескрипторы открытых файлов: например. текущий рабочий каталог; расположение игнорируемых сигналов и масок сигналов; умаскировать; состояние... - person caf; 28.10.2016
comment
@caf Спасибо, у меня было ощущение, что я упускаю некоторые детали. Я просто удалил это, так как это не очень важно для этого вопроса. - person Barmar; 28.10.2016
comment
@caf, как я сказал в другом комментарии к вопросу, среда указывается в вызове exec*(2), поэтому она также заменяется. Среда сохраняется в виртуальном пространстве процесса, и сохраняются только ресурсы, такие как открытые дескрипторы, которые не хранятся в виртуальном адресном пространстве процесса. Вызовы, которые не запрашивают новую среду, просто используют среду, полученную в качестве параметра для нового вызова exec*(2). Сохраняются только те открытые дескрипторы, которые не имеют флага O_CLOEXEC. Те, у кого он есть, будут закрыты. Вы также теряете все сегменты mmap(2)ed. - person Luis Colorado; 03.11.2016
comment
@LuisColorado Окружающая среда указана только в execve и execle. Но все это не имеет отношения к моему ответу, поэтому я убрал все упоминания о том, что осталось. - person Barmar; 03.11.2016
comment
@Barmar, я только сказал, что среда отображается в виртуальном пространстве процесса и поэтому не может быть сохранена. Ни один unix не сохраняет среду в системном месте, так как для доступа к ней потребуются системные вызовы. Другие execl(2) и execv(2) и их аналоги пути берут среду из глобальной переменной environ. Действительно, вы можете пройти NULL, и тогда вы вообще не получите никакого окружения. - person Luis Colorado; 03.11.2016
comment
@LuisColorado Разве это не то, что мы имеем в виду, говоря, что exec сохраняет окружающую среду? - person Barmar; 03.11.2016