我正在编写一个程序,其中有两个线程,第一个线程扫描输入文件(每行一个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, "%dn", &variable);
}
pthread_mutex_unlock(&thing);
return NULL;
}
void* meth2(void* param) {
if (variable % 2 == 0) {
pthread_mutex_lock(&thing);
fprintf((FILE*)param, "%dn", variable);
fprintf((FILE*)param, "%dn", variable);
pthread_mutex_unlock(&thing);
}
if (variable % 2 != 0) {
pthread_mutex_lock(&thing);
fprintf((FILE*)param, "%dn", 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;
}
在for循环你这样做:
pthread_mutex_lock(&thing);
while (!feof(ifile)) {
fscanf(ifile, "%dn", &variable);
}
pthread_mutex_unlock(&thing);
因此,您正在消耗整个文件并在每个循环中为变量赋值。没有机会写3以外的东西。
EDIT:
下面的代码没有直接回答这个问题,但它是一个解决你的问题的方法。
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <string.h>
using namespace std;
int main()
{
fstream f_input;
fstream f_output;
/* Open input file */
f_input.open("input.txt",ios::in);
if (!f_input.is_open())
{
cout << "Unable to open input file" << endl;
return 0;
}
/* Open out file */
f_output.open("output.txt",ios::out);
if (!f_output.is_open())
{
cout << "Unable to open output file" << endl;
return 0;
}
/* Iterate thru the file per line*/
string last_line;
char *p_last_line;
int i_last_line_integer;
unsigned int ui_last_line_len;
do
{
getline(f_input, last_line);
p_last_line = (char *)last_line.data();
sscanf(p_last_line,"%d", &i_last_line_integer);
ui_last_line_len = last_line.length();
if (i_last_line_integer %2 == 0) /* it's even, write twice */
{
f_output.write(p_last_line,ui_last_line_len);
f_output.write("n", ui_last_line_len);
f_output.write(p_last_line,ui_last_line_len);
f_output.write("n", ui_last_line_len);
}
else /* it's odd, write once */
{
f_output.write(p_last_line,ui_last_line_len);
f_output.write("n", ui_last_line_len);
}
}while(!f_input.eof());
f_input.close();
f_output.close();
return 0;
}
旧:
我看到你在创建第一个线程后立即调用join函数。join函数等待线程结束,所以如果你想让两个线程同时运行,你应该将这段代码重写为:
pthread_t thread1, thread2;
pthread_create(&thread1, NULL, meth1, NULL);
pthread_create(&thread2, NULL, meth2, args.file);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
然而,我不认为这是你真正想要完成的,你想让代码首先读取第一个文件并将数字输出到第二个文件吗?如果是这样,您可以同时打开两个文件,并在读取变量后的每个循环将其打印到第二个文件中,因为此时第二个线程实际上只执行一次。现在,下一个代码是如何使用互斥锁来防止变量同时被两个线程访问,但不修复算法,如果它的工作是读取并复制到另一个文件,以防剩余的除法为0:
#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;
}
while (!feof(ifile))
{
pthread_mutex_lock(&thing);
fscanf(ifile, "%dn", &variable);
pthread_mutex_unlock(&thing);
}
return NULL;
}
void *meth2(void *param)
{
pthread_mutex_lock(&thing);
if (variable % 2 == 0)
{
fprintf((FILE *)param, "%dn", variable);
fprintf((FILE *)param, "%dn", variable);
}
else
{
fprintf((FILE *)param, "%dn", 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, thread2;
pthread_create(&thread1, NULL, meth1, NULL);
pthread_create(&thread2, NULL, meth2, args.file);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
fclose(ofile);
pthread_mutex_destroy(&thing);
return 0;
}