我正在尝试使用信号量和 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);
}
问题是我的代码,在读取整个文件后,在某些运行中会冻结(可能在无限循环中)。而且,即使我在阅读后弹出它,两个消费者函数也会读取相同的单词。此外,打印已读取的数组元素的部分只是打印空白。为什么会出现这些问题?我是线程的新手(就像使用线程编码一样,我知道线程的理论概念)所以请帮我解决这个问题。
pthreads 标准禁止在一个线程中访问一个对象,而另一个线程正在或可能正在修改它。您的wait
和signal
函数通过semaphore
在signal
线程调用wait
可能正在访问它时修改(in )来违反此规则。你也这样做counter
。
如果你在做什么signal
并且wait
是合法的,你就不需要signal
and wait
。您可以像直接访问一样直接访问队列semaphore
。如果队列需要保护(我希望您知道),那么semaphore
出于完全相同的原因也需要保护。
允许编译器优化此代码:
while(semaphore<=0);
对于此代码:
if (semaphore<=0) { while (1); }
为什么?因为它知道semaphore
当这个线程可以访问它时,没有其他线程可能修改它,因为这是标准禁止的。因此,没有理由多读一次。
您需要使用实际的信号量和/或锁。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句