【发布时间】:2018-02-15 15:57:50
【问题描述】:
我正在 CentOS 7.3 中使用 Code::Blocks 16.01 编写程序。该程序包含主函数和由 clone() 函数创建的子进程(或所谓的线程)。我的目的是通过去掉 CLONE_FS 参数来测试 chdir() 函数是否影响主函数中的工作目录。希望它有效,但会出现新问题。请先阅读我的代码:
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sched.h>
#include <fcntl.h>
#define STACK_SIZE 1024*1024*8
int thread_func(void *arg){
int i;
char *cdir;
for(i = 0; i < 100; i++){
switch(i%3){
case 0:
chdir("/home/centos/dirtest/dir000");
break;
case 1:
chdir("/home/centos/dirtest/dir001");
break;
case 2:
chdir("/home/centos/dirtest/dir002");
break;
}
cdir = getcwd(NULL,0);
fprintf(stderr,"Child Thread in # %d: %s\n",i,cdir);
}
free(cdir);
return 1;
}
int main(){
void *pstack = (void*)mmap(NULL, STACK_SIZE,
PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_ANON,
-1, 0);
if(MAP_FAILED != pstack){
int ret,i;
char *cdir;
ret = clone(thread_func,
(void*)((unsigned char *)pstack + STACK_SIZE),
CLONE_VM | CLONE_FILES ,
NULL);
if(ret == -1){
fprintf(stderr,"Thread create failed\n");
return 0;
}
for(i = 0; i < 100; i++){
cdir = getcwd(NULL,0);
fprintf(stderr,"Main Function in # %d: %s\n",i,cdir);
}
free(cdir);
}
return 1;
}
但是,当我通过命令行在终端中运行生成的 exe 文件时,它卡住了。主函数和子进程都无法完成它的“for”循环,我不得不按“Ctrl-C”终止程序。
有人能找到问题吗?
********这里是新进展的编辑********
感谢 cmets,我对 getcwd() 函数进行了更改。我还添加了 waitpid() 函数。但是,它显示失败。修改后的代码如下:
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <sched.h>
#include <fcntl.h>
#define STACK_SIZE 1024*1024*8
int thread_func(void *arg){
int i;
char cdir[1024];
for(i = 0; i < 100; i++){
switch(i%3){
case 0:
chdir("/home/centos/dirtest/dir000");
break;
case 1:
chdir("/home/centos/dirtest/dir001");
break;
case 2:
chdir("/home/centos/dirtest/dir002");
break;
}
getcwd(cdir,sizeof(cdir));
fprintf(stderr,"Child Thread in # %d: %s\n",i,cdir);
}
return 1;
}
int main(){
/*void *pstack = (void*)mmap(NULL, STACK_SIZE,
PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS ,
-1, 0);
if(MAP_FAILED != pstack){*/
void *pstack = malloc(STACK_SIZE);
int ret,i;
char cdir[1024];
ret = clone(thread_func,
(void*)((char *)pstack + STACK_SIZE),
CLONE_VM | CLONE_FILES | CLONE_SIGHAND | CLONE_THREAD,
NULL);
if(ret == -1){
fprintf(stderr,"Thread create failed\n");
goto mem;
}
for(i = 0; i < 100; i++){
getcwd(cdir,sizeof(cdir));
fprintf(stderr,"Main Function in # %d: %s\n",i,cdir);
}
ret = waitpid(ret,0,0);
if(ret == -1){
fprintf(stderr,"waitpid failed\n");
}
mem:
//}
free(pstack);
return 1;
}
【问题讨论】:
-
您的进程可以创建的线程数是否有限制?这个限制小于100吗?更严重的是,您是否释放了足够的内存?您在
thread_func()中从getcwd()泄漏了100 个返回值中的99 个,在main()中从getcwd()泄漏了另外100 个返回值中的99 个。 -
乔纳森·莱弗勒,感谢您的评论。 getcwd() 是关键问题。现在我修改了这个调用,但是又出现了一个问题:main函数虽然完成了它的循环,但是子线程没有。
标签: c linux multithreading clone