저는 Linux에서 C/C++ (일부 레거시 코드 포함)의 스레딩을 통해 수백만 개의 폴더를 개별적으로 복사하는 작업을 제공 받았습니다.스레드 동기화 문제
폴더 검색, 원본에서 대상 폴더로의 파일 복사와 같은 개별 기능이 있으며, 연속적으로 실행하면 제대로 작동합니다. 스레딩을 통해 완료되면 모든 문제가 발생합니다.
문제 : 코드는 실행될 때마다 약간 다르게 작동합니다. 때로는 폴더 전체 목록을 proeprly로 복사하지만 때로는 실패합니다.
실패한 샘플 출력은 다음 함수에
foldername is [Junk] tCount is 2 cntr is 3
val of folder is Junk tid is 3055356816
foldername is [Notes] tCount is 3 cntr is 4
val of folder is tid is 3042966416
Folder creation failed /var/anshul/work/copyDirectoryThreaded/test_copied/email/
통과 인수의 값 NULL
스레드된다. 위의 경우에는 Notes
인수가 main 함수에서 thread 함수로 전달되었지만 thread 함수에서 수신 된 값은 NULL
입니다.
내 주요 코드는 다음과 같습니다
int main()
{
int cntr=0;
int Val = 3;
tCount = 0;
pthread_t thread[folderCount]; // folderCount is total number of folders scanned
int iret[folderCount];
std::map<std::string,int>::iterator mFolderIt; // mFolder map contains the folder list.
char foldername[30] = {0};
for (mFolderIt=mFolder.begin() ; mFolderIt != mFolder.end();)
{
if(tCount < Val)
{
pthread_mutex_lock(&mutex_tCount);
tCount++;
pthread_mutex_unlock(&mutex_tCount);
sprintf(foldername,"%s",(*mFolderIt).first.c_str());
fprintf(stderr, "foldername is [%s] tCount is %d cntr is %d\n",foldername,tCount,cntr);
iret[cntr] = pthread_create(&thread[cntr], NULL,folderCopy , (void*)foldername);
cntr++;
usleep(1); // most crucial for threading.......
mFolderIt++;
memset(foldername,0,30);
}
else
{
while(tCount >= Val)
{
usleep(10);
}
}
}
for(int x = 0 ; x<folderCount ;x++)
pthread_join(thread[x],NULL);
return 1;
}
스레드 기능 코드 :
void * folderCopy(void *f)
{
fprintf(stderr,"val of folder is %s tid is %u\n", folder, (unsigned int)pthread_self());
pthread_mutex_lock(&mutex_tCount);
tCount--;
pthread_mutex_unlock(&mutex_tCount);
pthread_exit(NULL);
return NULL;
}
누군가가 나에게이 문제를 해결하는 데 도움이 바랍니다 수 있습니다.
문제를 해결하기 위해 스레드 풀 패턴을 사용하는 것이 좋습니다. 어쨌든, 코드에서 대기 루프보다는 스레드를 동기화하는 데 std :: condition_variable을 사용하는 것이 더 좋습니다. –
'usleep (1); // 스레딩에 가장 중요합니다 ....... "는 나에게 밝히고있는 밝은 붉은 깃발이다 :"나는 깨졌어! ". pthread_create에 전달하기 위해'foldername'의 사본을 만들고, 쓰레드가 끝날 때 쓰레드에서 해제하십시오. – JimR
heehe Jim, 정확히 ... !!! 큰소리로 외치는 것이 더 낫습니다. :-) –