2013-11-27 3 views
0

프로그램은 매개 변수로 3 개의 파일 이름을 사용하고 2 개의 스레드를 만들고 첫 번째 스레드에서 첫 번째 파일을 읽고 두 번째 스레드는 두 번째 파일에서 읽고 두 번째 파일은 세 번째 파일에 기록해야합니다. 궁극적으로 그들은 읽고있는 파일의 각 행을 세 번째 파일로 대체해야합니다. 내가 프로그램을 실행할 때 그들은 실제로 대체하지 않는다. 때로는 한 스레드가 모든 행을 파일에 쓰고, 다른 스레드는 모든 행을 파일에 씁니다. 때로는 한 줄씩 번갈아 가며, 한 번은 한 줄, 두 번은 한 번씩 번갈아 가며 사용합니다. 누군가가 쓰기 방향으로 나를 가리켜 서 각 스레드가 파일에 대체 쓰기를 할 수있게 할 수 있습니까? 세 번째 매개 변수를 sem_init 함수로 변경하면 스레드가 대체되는 방식에 영향을 미친다는 것을 알게되었습니다.세마포어와 C의 스레드

#include <stdlib.h> 
#include <stdio.h> 
#include <pthread.h> 
#include <semaphore.h> 
#include <errno.h> 


#define BADFILE 2 
#define BADPARAM 3 
#define DEBUG 1 

sem_t mutex; 

typedef struct { 
    char *file; 
    FILE *mf; 
} read_args; 

void error(char *msg, int code) 
{ 
    fprintf(stderr, "Error: %s\nAborting.\n", msg); 
    exit(code); 
} 

void *readFile1(void *p) 
{ 

    read_args *param = (read_args *)p; 
    FILE *f1; 
    char *line; 
    size_t len = 0; 
    ssize_t read; 
    int lineCount = 1; 
    f1 = fopen(param->file, "r"); 
    if(f1 == NULL) 
    { 
     error("File not found.", BADFILE); 
    } 


    while((read = getline(&line, &len, f1)) != -1) 
    { 
     sem_wait(&mutex); 
     fprintf(param->mf,"%s: %d: %s", param->file, lineCount,line); 

#if DEBUG   
     printf("%s: %d: %s", param->file, lineCount,line); 
#endif 

     sem_post(&mutex); 
     lineCount++; 
    } 
    fclose(f1); 
    pthread_exit(NULL); 
} 

void *readFile2(void *p) 
{ 

    read_args *param = (read_args *)p; 
    FILE *f1; 
    char *line; 
    size_t len = 0; 
    ssize_t read; 
    int lineCount = 1; 
    f1 = fopen(param->file, "r"); 
    if(f1 == NULL) 
    { 
     error("File not found.", BADFILE); 
    } 
    //sem_wait(&mutex); 
    while((read = getline(&line, &len, f1)) != -1) 
    { 
     sem_wait(&mutex); 
     fprintf(param->mf,"%s: %d: %s", param->file, lineCount,line); 

#if DEBUG   
     printf("%s: %d: %s", param->file, lineCount,line); 
#endif 

     sem_post(&mutex); 
     lineCount++; 
    } 

    fclose(f1); 
    pthread_exit(NULL); 
} 


int main(int argc, char **argv) 
{ 
    FILE *f; 
    char *mergedfile; 
    pthread_t tid1, tid2; 
    read_args *p1; 
    read_args *p2; 
    p1 = malloc(sizeof(read_args)); 
    p2 = malloc(sizeof(read_args)); 
    if(argc != 4) 
    { 
     error("Invalid parameters. Proper use: ./merge <file1> <file2>" 
      " <mergedfile>", BADPARAM); 
    } 

    p1->file = argv[1]; 
    p2->file = argv[2]; 

    mergedfile = argv[3]; 
    f = fopen(mergedfile, "w"); 
    if(f == NULL) 
    { 
     error("Can't open file.", BADFILE); 
    } 
    p1->mf = f; 
    p2->mf = f; 

    sem_init(&mutex, 0, 3); 
    if(pthread_create(&tid1, NULL, readFile1, (void*)p1) < 0) 
    { 
     error("Can't create first thread", EXIT_FAILURE); 
    } 
    if(pthread_create(&tid2, NULL, readFile2, (void*)p2) < 0) 
    { 
     error("Can't create second thread", EXIT_FAILURE); 
    } 
    if(pthread_join(tid1, NULL) < 0) 
    { 
     error("Can't join first thread", EXIT_FAILURE); 
    } 
    if(pthread_join(tid2, NULL) < 0) 
    { 
     error("Can't join second thread", EXIT_FAILURE); 
    } 
    sem_destroy(&mutex); 

    fclose(f); 
    return(EXIT_SUCCESS); 

} 
+0

[C++의 스레드를 교대로 사용하여 인쇄하는 홀수 및 짝수 인쇄] 가능한 복제본 (http://stackoverflow.com/questions/14641134/printing-odd-and-even-number-printing-alternately-using-threads- in-c) –

+0

나는 규칙에 따라 올바르게 /하고 있는지 확실하지 않지만 사이트에 새로운 회원입니다.하지만 감사합니다 덕. 그것을 고쳐 준 도움을 감사하십시오. 또한이 질문이 중복되는 경우 미안합니다. – user3040106

답변

0

뮤텍스와 같은 세마포어를 사용하고 있습니다. 그것은 하나의 스레드 쓰기를 유지하고 다른 하나는 차단되지만 실행 순서의 보장은 없습니다. 동일한 스레드가 세마포어를 한 번에 여러 번 획득 할 수 있음을 발견했습니다. 각 스레드는 자신의 순서대로 상대방에게 신호를 보내야합니다. 그들은 게시하여이 작업을 수행합니다.

두 번째 세마포를 사용하는 경우 스레드를 강제로 대체 할 수 있습니다. Thread1은 mutex1에서 대기하고 mutex2에 게시해야합니다. Thread2는 mutex2에서 대기하고 mutex1에 게시합니다. Mutex1은 1로 초기화해야만 처음으로 갈 수 있습니다. mutex2는 0으로 초기화되므로 thread1이 먼저 실행될 때까지 대기해야하므로 아무것도 수행 할 수 없습니다. pthread_exit 전에 다른 스레드의 뮤텍스에 게시해야합니다. 그렇지 않으면 다른 스레드가 더 읽을 수 있지만 교착 상태가됩니다.

lineCount의 증가분은 스레드간에 공유 된 이후에 임계 영역 내에 두어야합니다.

관련 문제