我尝试用 clone-execl 替代 system()
但是怎么给 clone() 分配一个合适的 Stack_Size 而不是分配一个过大的内存?
下面是代码
static int Child(void *arg){
execl("/bin/ls", "ls", "-alh", "--color=auto", "NULL");
return 0;
}
char run_program(void){
int STACK_SIZE = 10000;
void *Child_Stack = calloc(STACK_SIZE, sizeof(char));
if (Child_Stack == NULL){
return 'X';
}
if (clone(Child, Child_Stack + STACK_SIZE, CLONE_VFORK, NULL) == -1){
free(Child_Stack);
return 'X';
}
return 'V';
}
另外,return 'V'; 上面有没有必要加上 free(Child_Stack)?
先多谢各位了
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
你这个并不需要分配多大的栈,因为在execl后,子线程就完全独立了,并不会和父进程共享内存空间,和fork没什么区别,我测试时只需要大概1200个字节就可以了。
因为execl后那段分配的栈空间就没有用处了,所以free掉比较好。
参考 stackoverflow
@fplust 刚起床又测试了一次,发现clone需要的stack_size是clone调用的函数所需要的内存大小,低于就会execl失败。
比如
在上面的代码中的Child函数里加上 char ABC[10];
Stack_Size就要增加16字节才能成功执行execl
另外,如果在char ABC[10];上面加上printf之类的就算execl失败也会成功输出
感觉像我这样一个个字节的给他增加有点傻。。。再等等看你们有什么方法
int stacktop;
....
int stackdown;
stacksize = &stacktop - &stackdown;
execl(...);
clone(Child, Child_Stack + stacksize + PADDING ....)
利用以下几点:
1.栈是向下增加。所以可以用两个变量找出这个位置。
2.execl不会返回,它不需要栈来保存返回值,只需要保存栈顶位置就可以。
3.PADDING是一次函数调用的栈开销,这是一个固定值。
缺点:
1.第一次,stacksize需要足够大。
2.child中不调用其它函数,如果需要调用其它函数,需要考虑最深的函数要用多少栈。
另外也可以通过向栈填特殊标志的方式找到最深的栈位置。