다중 쓰레드에서 디렉토리 삭제 문제 ?

kiss의 이미지

안녕하세요.

디렉토리와 쓰레드 관련해서 질문 드리려고 합니다.

질문 1. 다중 쓰레드에서 디렉토리를 삭제할 때 문제

프로그램 순서 :

1. 프로그램 Test 에서 쓰레드 5개를 생성
2. 쓰레드 5개가 각각 다른 디렉토리를 삭제

thread 1 -> /prgram1/d1 하위 디렉토리 d11, d12
thread 2 -> /prgram1/d2 하위 디렉토리 d21, d22
thread 3 -> /prgram1/d3 하위 디렉토리 d31, d32
thread 4 -> /prgram1/d4 하위 디렉토리 d41, d42
thread 5 -> /prgram1/d5 하위 디렉토리 d51, d52

3. 디렉토리를 삭제할 때는 아래의 RemoveSubDirectory() 사용

BOOL RemoveSubDirectory(char * szDir) 
{ 
   DIR         * dp; 
   struct dirent   * entry; 
   struct dirent   * result;    
   struct stat   statbuf; 
   char         szPath[MAXPATH];    

   if(!IsExistFile(szDir))  
   { 
      return TRUE; 
   } 
    
   if( !(dp = opendir(szDir)) ) 
   { 
      fprintf(stdout, "## Directory open error.\n");                
      return FALSE; 
   } 

   if( chdir(szDir) != 0 ) 
   { 
      fprintf(stderr,"## Directory change error. 1\n"); 
      return FALSE; 
   } 

   entry = (struct dirent *)malloc(sizeof(struct dirent) + MAXPATH); 

   while(readdir_r(dp, entry, &result) == 0 ) 
   { 
      if(!strcmp(entry->d_name , ".")||!strcmp(entry->d_name, "..")) 
         continue; 
       
      stat(entry->d_name, &statbuf); 
       
      if (S_ISDIR(statbuf.st_mode))         /* 디렉토리 */ 
      { 
         sprintf(szPath, "%s/%s", szDir, entry->d_name); 
         RemoveSubDirectory(szPath); 
      } 
      else if (S_ISREG(statbuf.st_mode))      /* 일반 파일 */ 
      { 
         sprintf(szPath, "%s/%s", szDir, entry->d_name); 
         unlink(szPath); 
      } 
      else if (S_ISLNK(statbuf.st_mode)) 
      { 
         sprintf(szPath, "%s/%s", szDir, entry->d_name); 
         unlink(szPath);          
      } 
   } 
    
   free(entry); 
   closedir(dp); 

   if(chdir("..") != 0) 
   { 
      fprintf(stderr,"## Directory change error. 2\n"); 
   } 

    
   if (rmdir(szDir) != 0) 
   { 
      fprintf(stderr,"## Directory delete error\n"); 
      return FALSE;          
   } 
} 

이렇게 할 때 가끔 씩

## Directory change error. 2 와

## Directory delete error 가 발생합니다.

"## Directory delete error"가 발생하는 원인을 찾아 보면

해당 디렉토리에 파일이 있어 그런 에러가 발생합니다.

예를 들어 thread 1이 해당 디렉토리에서 작업 하고 있는데

다른 thread 에서 다른 디렉토리로 이동하면서 thread 1에 영향을

주는 것이 아닐까 추측만 하고 있습니다.

어떤 문제가 있는지 아시는 분은 꼭 좀 답변 부탁드립니다.

(또한 쓰레드에서 디렉토리를 정확히 삭제하는 방법에 대해서도)

질문 2. (질문 1과 이어지는 질문)

thread에서 getcwd((char *)szPath, sizeof(szPath)); 함수를

사용하면 가끔씩 값을 못구하는 경우가 있습니다.

getcwd 함수가 thread safe 하지 못해서 발생하는 것 인가요 ?

답변 좀 부탁드립니다.

수고하세요.

sjang의 이미지

제 옆에 사람이 비슷한 경험을 했지요.

chdir()이 문제였습니다.

하나의 프로세서 안에서 작업 디렉토리가 바뀌지요.

즉, 하나의 프로세서 안에 있는 쓰레드들에게 영향을 미친다는 뜻이죠.

그래서, 해결책은.... 쓰레드 안에서 fork()한 뒤에 chdir()를 이용했다는...

이 방법 말고 디렉토리 이동해서 하는 작업은 mutex를 걸어서 하는 방법 밖에

없는지 저도 잘은 모릅니다.

그럼~

The Future !!!

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.