Я учусь использовать clone
метод (только CLONE_VM) для создания дочерних потоков с c на ubuntu18. Когда у родительского потока нет метода sleep
или printf
, дочерний поток может нормально работать после выхода из родительского потока. К сожалению, когда родительский поток имеет sleep
или printf
, дочерний процесс будет убит при выходе из родительского потока. Я не знаю, как это должно работать.
Вот мой код:
int child_proc(void *args)
{
int a = *((int *)args);
//sleep(1);
printf("child receive a arg: %d\n", a);
exit(1);
}
int main(void)
{
int cpid, arg = 45, clone_flags = CLONE_VM;
char *stack = malloc(MAXSPACE); //space
printf("arg -> %d\n", arg);
cpid = clone((void *)child_proc, &(stack[MAXSPACE-1]), clone_flags, (void *)(&arg));
sleep(2);
printf("cpid %d\n", cpid);
return 0;
}
и вот результат:
$ ./clone.o
arg -> 45
child receive a arg: 45
cpid 4685
Результат выглядит хорошо, когда я меняю метод сна:
int child_proc(void *args)
{
int a = *((int *)args);
sleep(1);
printf("child receive a arg: %d\n", a);
exit(1);
}
int main(void)
{
int cpid, arg = 45, clone_flags = CLONE_VM;
char *stack = malloc(MAXSPACE);
printf("arg -> %d\n", arg);
cpid = clone((void *)child_proc, &(stack[MAXSPACE-1]), clone_flags, (void *)(&arg));
//sleep(2);
printf("cpid %d\n", cpid);
return 0;
}
Кажется нормальным:
$ ./clone.o
arg -> 45
cpid 4845
Дочерний поток не выводил, потому что родительский поток завершился, но когда я удаляю все методы sleep
и printf
в родительском методе:
int child_proc(void *args)
{
int a = *((int *)args);
sleep(1);
printf("child receive a arg: %d\n", a);
exit(1);
}
int main(void)
{
int cpid, arg = 45, clone_flags = CLONE_VM;
char *stack = malloc(MAXSPACE);
//printf("arg -> %d\n", arg);
cpid = clone((void *)child_proc, &(stack[MAXSPACE-1]), clone_flags, (void *)(&arg));
//sleep(2);
//printf("cpid %d\n", cpid);
return 0;
}
Это кажется довольно странным:
$./clone.o
$ child receive a arg: 32767
Первая строка сразу выходит, а вторая появляется.
Через 1 секунду выводится дочерний поток.
После вывода во второй строке я могу набрать команду напрямую. Я не знаю, как это должно работать. Кто-нибудь может мне помочь?