私はCentOS 7.3でCode :: Blocks 16.01を使ってプログラムを書いています。このプログラムには、main関数と、clone()関数によって作成された子プロセス(またはいわゆるスレッド)が含まれています。私の目的は、chdir()関数がCLONE_FSパラメータを削除することによってメイン関数の作業ディレクトリに影響するかどうかをテストすることです。うまくいけばうまくいきますが、新しい問題が発生します。私のコードを先に読んでください:GNUのclone()関数がスタックしました
#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"でプログラムを終了しなければなりませんでした。
誰でも問題を見つけることができますか?
********はここで、私は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個を漏らしています。 –
Jonathan Leffler、ご意見ありがとうございます。 getcwd()は重要な問題です。今度はこの呼び出しを修正しましたが、次のように別の問題が発生します。main関数はループを終了しますが、子スレッドは終了しません。 –