2013-11-27 142 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-在-C) –

+0

我是一個新成員網站,所以我不知道如果我正確地做這個/根據規則,但由於鴨;修復它,欣賞幫助。另外,如果這是一個重複的問題,很抱歉。 – user3040106

回答

0

您使用的信號量就像一個互斥量。這將保持一個線程寫入,另一個線程被阻塞,但不能保證執行的順序。正如你發現同一個線程可以連續多次獲取信號量。每個線程都需要告訴對方輪到他們去。他們通過發佈完成此操作。

如果使用第二旗語,您可以強制線程交替。線程1需要等待互斥量1併發布到互斥量2。線程2在互斥體2和帖子上等待互斥體1。互斥量1需要初始化爲1,以便它可以先到達; mutex2被初始化爲0,因此它必須等到thread1先運行併發布後纔可以執行任何操作。請確保您張貼到其他線程的互斥你了pthread_exit否則其他線程之前,可能有更多的閱讀,但它會陷入僵局。

你也應該把lineCount的增量的關鍵部分,因爲裏面它的線程之間共享。