2017-09-23 14 views
0

두 개의 스레드를 만드는 프로그램을 작성하고 있습니다. 각 스레드는 하나의 텍스트 파일을 읽고 각 행에 하나의 문자를 읽어야합니다. 두 번째는 같은 포맷Pthread 동기화 : 두 개의 텍스트 파일을 앞뒤로 읽음

h 
0 
h 
0 
... 

: 같은

첫 번째

는 포맷
0 
i 
0 
i 
0 
i 

때때로 서로 후 여러 문자, 또는 서로 후 여러 제로가있을 수 있습니다. 그러나 한 파일의 한 줄에 문자가있는 경우 두 번째 파일의 해당 줄에는 0이 있고 그 반대의 경우도 마찬가지입니다.

스레드는 파일 입력이 0에 도달 할 때까지 전역 문자 배열로 계속 읽어야합니다. 이 시점에서 다른 스레드가 인계 할 수 있습니다. 그리고 그들은 두 파일이 완전히 읽힐 때까지 앞뒤로 계속 가고 있습니다. 내가 실행할 때이 시점에서

, 나는의 변화를 얻을 중 하나 (1) 내가 년대 또는 (2) (정답) hihihi 년대의 연속 스트림, 또는 (3) 때로는 많은 내가 년대 많은 다음에 많은 시간의 그 다음으로 많은 h가 뒤 따른다. 그래서, 나는 나의 동기화 방법이 꺼져 있음을 안다. (두 스레드가 열려있는 파일을 제외하고 정확히 동일합니다.) 여기

void *getMessage1() 
{ 
FILE *studentOne = fopen("Student1", "r"); 

size_t howManyChars; 
char *placeHolderChars; 
int count = 1; 
while (count < 501) 
{ 
    placeHolderChars = NULL; 
    getline(&placeHolderChars, &howManyChars, studentOne); 

    if(strcmp(placeHolderChars, "0\n") == 0) //if we've reached a zero 
    { 

     pthread_mutex_unlock(&lock); 
    } 
    else 
    { while(1) 
     { 
      if(pthread_mutex_trylock(&lock) == 0) 
      { 

       break; 
      } 
     } 

     if(strlen(placeHolderChars)>0) 
     { 
      placeHolderChars[1] = '\0'; 
     } 

     strcat(message,placeHolderChars); 
    } 

    free(placeHolderChars); 

    if(feof(studentOne)) 
    { 

     pthread_mutex_unlock(&lock); //unlock 
     fclose(studentOne); 
     break; 
    } 
    count++; 

} 

return 0; 
} 

내 주요 방법 :

int main(void) 
{ 
pthread_t id1; 
pthread_t id2; 

pthread_create((&id1), NULL, getMessage1, NULL); 
pthread_create((&id2), NULL, getMessage2, NULL); 

pthread_join(id1, NULL); 
pthread_join(id2, NULL); 

int j; 

for (j = 0; j < 1001; j++) 
{ 
    printf ("%c ",message[j]); 
} 

return 0; 
} 
여기

내 스레드 중 하나의 예입니다

잠금, 잠금 해제, 대기 및/또는 신호를 사용하여 일관된 결과로 작동하는 동기화 기술을 만드는 방법에 대한 지침을 주시면 감사하겠습니다.

+0

세마포어. 뮤텍스로는이 작업을 수행 할 수 없습니다. 복수형. –

+0

제 교수는 뮤텍스를 사용하는 것이 실제로 더 쉽다고 주장했기 때문에 뮤텍스를 사용하도록 제안했습니다. 그래서, 뮤텍스를 스크랩하고 바이너리 세마포어를 사용해야합니까? – Selena

+0

또한 두 스레드가 사용하는 하나의 함수 만 있다고 생각합니까? (그리고 파일을 매개 변수로 전달합니까?) 어떤 차이가 있습니까? – Selena

답변

1

다음은 원하는대로하는 프로그램에서의 시도입니다. 그래도 불충분하게 테스트 됨)

#include <iostream> 
#include <fstream> 
#include <string> 

#include <cassert> 
#include <pthread.h> 



using std::cout; 
using std::ifstream; 
using std::string; 

const string FILE1("file1.txt"); 
const string FILE2("file2.txt"); 

enum State 
{ 
    UNINITIALIZED, 
    THREAD_ONE_READS, 
    THREAD_TWO_READS 
}; 

struct ThreadInfo 
{ 
    State state; 
    string filename; 
}; 

State state = UNINITIALIZED; 
pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; 
pthread_cond_t cond = PTHREAD_COND_INITIALIZER; 

void* thread_func(void* arg) 
{ 
    // Open file 'h'.                                                                                                     

    ThreadInfo ti = *reinterpret_cast<ThreadInfo*>(arg); 
    ifstream infile; 
    infile.open (ti.filename.c_str(), std::ifstream::in); 

    // while (not EOF)                                                                                                     
    // Read 'h' or 'i': until 0 reached. Wake up other thread.                                                                                          

    string line; 
    getline(infile, line); 
    while (infile.good()) 
    { 
     cout << "Thread " << pthread_self() << " read " << line << '\n'; 
     pthread_mutex_lock(&mut); 
     while (state == ti.state) 
     { 
      pthread_cond_wait(&cond, &mut); 
     } 
     pthread_mutex_unlock(&mut); 

     assert(line.length() == 1); 
     if (line[0] == '0') 
     { 
      pthread_mutex_lock(&mut); 
      state = ti.state; 
      cout << "Got 0, transferring, setting state to " << state << '\n'; 
      pthread_cond_signal(&cond); 
      pthread_mutex_unlock(&mut); 
     } 
     else 
     { 
      cout << "Read char: " << line << '\n'; 
     } 
     getline(infile, line); 
    } 

    pthread_mutex_lock(&mut); 
    state = ti.state; 
    cout << "Finishing thread, transferring, setting state to " << state << '\n'; 
    pthread_cond_signal(&cond); 
    pthread_mutex_unlock(&mut); 
} 

int main() 
{ 
    // Create thread 1                                                                                                     
    // Create thread 2                                                                                                     

    pthread_t thread_one_handle; 
    pthread_t thread_two_handle; 
    state = THREAD_ONE_READS; 
    int result; 

    ThreadInfo info1 = { THREAD_TWO_READS, FILE1 }; 
    result = pthread_create(&thread_one_handle, NULL, thread_func, &info1); 
    assert(result == 0); 

    ThreadInfo info2 = { THREAD_ONE_READS, FILE2 }; 
    result = pthread_create(&thread_two_handle, NULL, thread_func, &info2); 
    assert(result == 0); 

    result = pthread_join(thread_one_handle, NULL); 
    assert(result == 0); 
    result = pthread_join(thread_two_handle, NULL); 
    assert(result == 0); 
    cout << "main(): joined both worker threads, ending program.\n"; 

    return 0; 
} 
+0

@Selena이게 도움이 되었습니까? 나는 같은 질문을 두 번 게시하고 다른 질문에 대한 대답을 받아 들였다. ( –

+0

나는이 질문이 항상 C로만 태그되었고 C++로 태그가 붙지 않는다는 것을 관찰했다.하지만이 대답은 C++로되어있다. OP 같은 주제에 대해서도 같은 질문에 대해 다른 질문을 언급했습니다. (상단의 주석에 있습니다) –

+0

@JonathanLeffler : C++의 특정 기능을 사용하는 것이 매우 제한적이기 때문에 old-skool C는 사소한 것이어야합니다. –