2013-11-27 187 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的增量的关键部分,因为里面它的线程之间共享。