![](/img/trans.png)
[英]Can you tell me why my function to select a random string from a linked list isn't working?
[英]Pthread producer/consumer homework problem. Can you tell me why my program isn't writing all the words from the file to output?
我必须为我的操作系统 class 编写一个 C 程序。 这是 Linux 的生产者/消费者问题。 问题描述说明主线代码为输入文件打开一个文件描述符,并创建了三个pthreads。 每个pthread是要执行不同的function。
文件描述符被传递给第一个 pthread,它从输入文件中逐行读取行到与第二个 pthread 共享的缓冲区中。 缓冲区大小为 10。
第二个 pthread 从共享缓冲区中读取行,并将每行拆分为一组单词。 然后将每个字读入与第三个 pthread 共享的第二个缓冲区。 第二个缓冲区大小为 20。
第三个 pthread 从第二个缓冲区读取字,计算读取的字数,并将每个字写入标准 output。
由于某种原因,我的算法无法将文件中的所有单词写入标准 output。 有时我会遇到分段错误,有时它只将一些单词打印到 output 然后退出,有时程序会挂起。 我无法弄清楚问题出在哪里。
我的代码:
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
// first shared buffer
char line_buffer[10][200];
int in1 = 0;
int out1 = 0;
// second shared buffer
char word_buffer[20][50];
int in2 = 0;
int out2 = 0;
// function for first pthread
void * one(void *arg) {
int file = *((int *)arg);
char next_char_buffer[1];
int n;
int i;
while ((n=read(file, next_char_buffer,1)) > 0) {
while ((in1 + 1) % 10 == out1) {
// first buffer full
sched_yield();
}
if (next_char_buffer[0] == '\n') { // end of line
line_buffer[in1][i] = '\0'; // null terminate string
in1 = ++in1 % 10;
i = 0;
}
else {
// read char to buffer
line_buffer[in1][i++] = next_char_buffer[0];
}
}
while ((in1 + 1) % 10 == out1) {
// first buffer full
sched_yield();
}
line_buffer[in1][0] = '\0'; // EOF signal for second thread
in1 = ++in1 % 10;
printf("Exit 1 \n");
pthread_exit(NULL);
}
// function for second pthread
void * two(void *arg) {
int i;
// left and right indexes of a word in the line
int l;
int r;
int lines = 0; // number of lines read
while (lines == 0 || line_buffer[out1][0] != '\0') {
while (in1 == out1) {
// first buffer empty
sched_yield();
}
l = 0;
r = 0;
while (line_buffer[out1][r] != '\0') {
if (line_buffer[out1][r] == ' ') {
while ((in2 + 1) % 20 == out2) {
// second buffer full
sched_yield();
}
while (l < r) {
// write char to second buffer
word_buffer[in2][i++] = line_buffer[out1][l++];
}
word_buffer[in2][i] = '\0'; // null terminate string
in2 = ++in2 % 20;
i = 0;
l++;
r++;
}
else {
r++;
}
}
out1 = ++out1 % 10;
lines++;
}
while ((in2 + 1) % 20 == out2) {
// second buffer full
sched_yield();
}
word_buffer[in2][0] = '\0'; // signal end of input
in2 = ++in2 % 20;
printf("Exit 2\n");
pthread_exit(NULL);
}
// function for third pthread
void * three(void *arg) {
int i = 0;
int words = 0; // word count
while(words == 0 || word_buffer[out2][0] != '\0') {
while (in2 == out2) {
// second buffer empty
sched_yield();
}
printf("%s \n\n", word_buffer[out2]);
words++;
out2 = ++out2 % 20;
i++;
}
printf("Word count: %d \n",words);
printf("Exit 3\n");
pthread_exit(NULL);
}
int main(int argc, char *argv[]) {
// Check for 2 arguments or raise error
if (argc != 2){
write(STDERR_FILENO,"Error 1\n",8);
exit(-1);
return -1;
}
// file descriptor
int file;
if ((file = open(argv[1], O_RDONLY, 0)) == -1) {
printf("Can't open file");
exit(-1);
return -1;
}
// create pthreads
pthread_t tid_1, tid_2, tid_3;
pthread_create(&tid_1, NULL, one, &file);
pthread_create(&tid_2, NULL, two, NULL);
pthread_create(&tid_3, NULL, three, NULL);
// join pthreads
pthread_join(tid_1,NULL);
pthread_join(tid_2,NULL);
pthread_join(tid_3,NULL);
// close the file
printf("Exit main");
exit(0);
return 0;
}
您的程序在没有任何同步的情况下从多个线程访问变量(例如in1
、 in2
等)。
这是一场数据竞赛,它是未定义的行为,并使您的程序的结果未定义——它可以做任何事情。
下一个错误是one()
和two()
中的i
可能未初始化使用——最好在声明变量时初始化它们。
下一个错误是two()
仅在找到空格时才发出单词,因此每行都吃掉最后一个单词。
修复了上述错误后,程序可以工作,但仍会出现数据竞争。 您需要使用_Atomic
类型来避免这种情况。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.