两个线程使用互斥锁访问同一文件,防止发生竞争条件

时间:2016-06-02 10:15:05

标签: c++ c multithreading mutex

我有两个线程(标记为0和1)。

每个进程访问一个输入文件(f1,f2 /全局变量)和一个输出文件。 (fout1,fout2 /全局变量)

一旦一个线程(比方说#0)按照某个标准完成其工作,它就会帮助另一个线程(#1)。

因此,当命令位于受互斥锁保护的区域时,线程#0现在可以是fscanf(f2)和fprintf(f2)。

当输入数据很小(100,500,1000,2000 ......等)时,之前完成其工作的线程将帮助另一个。

例如:

  • fout1:a(#1),b(#1),c(#1)...←由第1号线程处理
  • fout2(先完成):A(#1),B(#1),C(#1)......

但是当数据大小很大(前10000)时,两个线程只会照顾他们自己的工作"分别。 线程完成首先似乎没有帮助另一个。

例如:

  • fout1:a(#0),b(#0),c(#0)...←由线程#0处理
  • fout2(先完成):A(#1),B(#1),C(#1)......←由第1号线程处理

任何人都可以帮我吗? (LinuxOS)

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <sys/fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <pthread.h>
#define queueL 4

int Length, fd, rule1, rule2, done[2]={0}, breakflag[2]={0};
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t threadMutex = PTHREAD_MUTEX_INITIALIZER;
FILE *f1, *f2, *fout1, *fout2;

void *tmpF(void *t) {
int tid = (int)t, var;
int rule=(tid%2)==0?rule1:rule2;
FILE *f=(tid%2)==0?f1:f2;
FILE *fout=(tid%2)==0?fout1:fout2;

printf("rule[%d]: %d\n", tid, rule);
pthread_mutex_lock(&threadMutex);
printf("in thread#%d\n", tid);
fprintf(fout, "Thread[%d]\nmatched numbers:\n", tid);
pthread_mutex_unlock(&threadMutex);
sleep(1);

while (1) {
    if (tid%2==0) pthread_mutex_lock(&mutex1);
    else pthread_mutex_lock(&mutex2);
    if (fscanf(f,"%d",&var)==1) {
        if (var%rule==0)
            fprintf(fout, "%d(#%d) ", var,tid);
    }
    else {
        printf("Thread[%d] finishes it own process\n", tid);
        breakflag[tid] = 1;
        if (tid%2==0) pthread_mutex_unlock(&mutex1);
        else pthread_mutex_unlock(&mutex2);
        break;
    }
    if (tid%2==0) pthread_mutex_unlock(&mutex1);
    else pthread_mutex_unlock(&mutex2);
}

if (tid==0) {
    rule = rule2;
    f = f2;
    fout = fout2;
}
else {
    rule = rule1;
    f = f1;
    fout = fout1;
}

while (1) {
    if (tid%2==0) pthread_mutex_lock(&mutex2);
    else pthread_mutex_lock(&mutex1);

    if (breakflag[1-tid]==1) break;
    if (fscanf(f,"%d",&var)==1) {
        if (var%rule==0)
            fprintf(fout, "%d(#%d) ", var,tid);
    }
    else {
        printf("Thread[%d] helps Thread[%d] finishes it own process\n", tid, 1-tid);
        breakflag[1-tid] = 1;
        if (tid%2==0) pthread_mutex_unlock(&mutex2);
        else pthread_mutex_unlock(&mutex1);
        break;
    }
    if (tid%2==0) pthread_mutex_unlock(&mutex2);
    else pthread_mutex_unlock(&mutex1);
}

pthread_exit((void*)t);
}

int main()
{
int var, i, N=100, t;
char cha[20];
srand(time(NULL));
Length=0;

printf("How many numbers to produce?: ");
scanf("%d",&N);
FILE *f = fopen("data.txt","w");
for (i=0; i<N; i++) {
    fprintf(f,"%d ",rand()%200+1);
}
fclose(f);

f1 = fopen("data.txt","r");
f2 = fopen("data.txt","r");
fout1 = fopen("lab5_2_out1.txt","w");
fout2 = fopen("lab5_2_out2.txt","w");

f = fopen("rule.txt","r");
fscanf(f,"%s%s%s%s%s%d",cha,cha,cha,cha,cha,&rule1);
fscanf(f,"%s%s%s%s%s%d",cha,cha,cha,cha,cha,&rule2);
fclose(f);

pthread_mutex_lock(&threadMutex);
void *status;
pthread_t th[2], rdOut[2];
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_JOINABLE);

pthread_create(&th[0],&attr,tmpF,(void*)0);
pthread_create(&th[1],&attr,tmpF,(void*)1);
pthread_mutex_unlock(&threadMutex);

printf("main thread before join...\n");
pthread_join(th[0],&status);
pthread_join(th[1],&status);

fclose(f1);
fclose(f2);
fclose(fout1);
fclose(fout2);

printf("main thread ends...\n");
return 0;
}

0 个答案:

没有答案