【发布时间】:2019-09-07 04:45:37
【问题描述】:
我正在尝试使用信号量和 pthread 实现生产者-消费者问题操作系统。但我的输出与预期完全不同。这是我的代码:
#include<iostream>
#include<pthread.h>
#include<fstream>
#include<unistd.h>
#include<queue>
// define queue size
#define QUEUE_SIZE 5
// declare and initialize semaphore and read/write counter
static int semaphore = 1;
static int counter = 0;
// Queue for saving characters
static std::queue<char> charQueue;
// indicator for end of file
static bool endOfFile = false;
// save arrays
char consumerArray1[100];
char consumerArray2[100];
// function to wait for semaphore
void wait()
{
while(semaphore<=0);
semaphore--;
}
// function to signal the wait function
void signal()
{
semaphore++;
}
void *Producer(void *ptr)
{
int i=0;
std::ifstream input("string.txt");
char temp;
while(input>>temp)
{
wait();
charQueue.push(temp);
//std::cout<<"Producer:\nCounter: "<<counter<<" Semaphore: "<<semaphore<<std::endl;
counter++;
std::cout<<"Procuder Index: "<<i<<std::endl;
i++;
signal();
sleep(2);
}
endOfFile = true;
pthread_exit(NULL);
}
void *Consumer1(void *ptr)
{
std::cout<<"Entered consumer 1:"<<std::endl;
int i = 0;
while(counter<=0);
while(!endOfFile)
{
while(counter<=0);
wait();
//std::cout<<"Consumer1:\nCounter: "<<counter<<" Semaphore: "<<semaphore<<std::endl;
consumerArray1[i] = charQueue.front();
charQueue.pop();
i++;
counter--;
std::cout<<"Consumer1 index:"<<i<<" char: "<<consumerArray1[i]<<std::endl;
signal();
sleep(2);
}
consumerArray1[i] = '\0';
pthread_exit(NULL);
}
void *Consumer2(void *ptr)
{
std::cout<<"Entered consumer 2:"<<std::endl;
int i = 0;
while(counter<=0);
while(!endOfFile)
{
while(counter<=0);
wait();
//std::cout<<"Consumer2:\nCounter: "<<counter<<" Semaphore: "<<semaphore<<std::endl;
consumerArray2[i] = charQueue.front();
charQueue.pop();
i++;
counter--;
std::cout<<"Consumer2 index: "<<i<<" char: "<<consumerArray2[i]<<std::endl;
signal();
sleep(4);
}
consumerArray2[i] = '\0';
pthread_exit(NULL);
}
int main()
{
pthread_t thread[3];
pthread_create(&thread[0],NULL,Producer,NULL);
int rc = pthread_create(&thread[1],NULL,Consumer1,NULL);
if(rc)
{
std::cout<<"Thread not created"<<std::endl;
}
pthread_create(&thread[2],NULL,Consumer2,NULL);
pthread_join(thread[0],NULL);pthread_join(thread[1],NULL);pthread_join(thread[2],NULL);
std::cout<<"First array: "<<consumerArray1<<std::endl;
std::cout<<"Second array: "<<consumerArray2<<std::endl;
pthread_exit(NULL);
}
问题是我的代码在读取整个文件后在某些运行中冻结(可能处于无限循环中)。即使我在阅读后将其弹出,这两个消费者功能也会读取相同的单词。此外,打印已读取的数组元素的部分仅打印空白。为什么会出现这些问题?我是线程新手(就像使用线程编码一样,我知道线程的理论概念)所以请帮我解决这个问题。
【问题讨论】:
-
您正在做的事情需要适当的联锁修改机制,或者一些互斥机制。有任何一个都可以工作。两者都不是竞争条件、挂起代码等的秘诀。您需要学习互斥锁、临界区等无关的东西,但与线程问题相比,this is wrong:
while(!input.eof())是次要的。也没有任何输入验证。 -
@WhozCraig 我使用
wait和signal函数添加了互斥。这有什么问题? -
投反对票的原因是什么?这个问题有什么问题?
-
@ShantanuShinde 对于刚接触线程的人来说,开始尝试编写自己的同步原语是很奇怪的。这是一件非常复杂的事情,在您非常非常熟悉它们的使用方式之前不应该尝试。
-
@DavidSchwartz 好吧,我被分配了这样做的任务。
标签: c++ operating-system pthreads semaphore