【发布时间】:2021-11-23 20:38:10
【问题描述】:
我正在编写一个程序,其中有两个线程,第一个线程扫描输入文件(每行一个 int)并将数字分配给全局变量。然后第二个线程读取全局变量,如果偶数将其打印到文件中两次,如果奇数则仅打印一次。
例如,如果输入文件是:
1
2
3
那么输出文件应该是:
1
2
2
3
不幸的是,输出文件如下:
3
我可以在哪里放置我的互斥锁和解锁以获得正确的结果?
这是我的代码:
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <iostream>
#include <cstdlib>
using namespace std;
FILE* ifile;
int variable = 0;
pthread_mutex_t thing;
struct arguments {
FILE* file;
};
void* meth1(void* param) {
ifile = fopen("intput.txt", "r");
if (ifile == NULL) {
printf("couldn't open the file");
return 0;
}
pthread_mutex_lock(&thing);
while (!feof(ifile)) {
fscanf(ifile, "%d\n", &variable);
}
pthread_mutex_unlock(&thing);
return NULL;
}
void* meth2(void* param) {
if (variable % 2 == 0) {
pthread_mutex_lock(&thing);
fprintf((FILE*)param, "%d\n", variable);
fprintf((FILE*)param, "%d\n", variable);
pthread_mutex_unlock(&thing);
}
if (variable % 2 != 0) {
pthread_mutex_lock(&thing);
fprintf((FILE*)param, "%d\n", variable);
pthread_mutex_unlock(&thing);
}
return NULL;
}
int main() {
FILE* ofile;
ofile = fopen("output.txt", "w");
if (ofile == NULL) {
printf("couldn't open the file");
return 0;
}
arguments args;
args.file = ofile;
pthread_t thread1;
pthread_create(&thread1, NULL, meth1, NULL);
pthread_join(thread1, NULL);
pthread_t thread2;
pthread_create(&thread2, NULL, meth2, args.file);
pthread_join(thread2, NULL);
fclose(ofile);
pthread_mutex_destroy(&thing);
return 0;
}
【问题讨论】:
-
在这个例子中,我认为你根本不需要任何互斥锁。线程 1 在线程 2 之前完成(因为您调用了 join),并且没有同时共享任何变量。然而,不要使用 pthreads,而是看看 std::async (& std::future),或者至少是 std::thread、std::mutex 和 std::unique_lock。 (en.cppreference.com/w/cpp/thread/async)
-
即使这些线程同时运行,代码也不会工作。
meth1锁定互斥体,然后从输入文件中读取值,直到到达文件末尾。所以它读取的最后一个值是variable。然后它解锁互斥锁。如果幸运的话,meth2会看到写入的值。如果你不走运,meth2将已经运行,并且看到值 0。这种线程的锁步操作非常棘手,而且通常毫无意义。 -
我建议研究如何实施生产者-消费者系统。这是您尝试在此处创建的系统的名称。
-
生产者/消费者看起来像这样,现场演示onlinegdb.com/mjgUFDgG8