I am trying to implement the Producer-Consumer problem operating system using semaphore and pthread. But my output is totally different from expected. Here is my code:
#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);
}
The problem is my code, in some runs freezes(probably in an infinite loop) after the entire file has been read. And also both of the consumer functions read the same words even though I am popping it out after reading. Also the part of printing the array element that has been read just prints blank. Why are these problems happening? I am new to threads(as in coding using threads, I know theoretical concepts of threads) so please help me with this problem.
答案 0 :(得分:2)
pthreads标准禁止在一个线程正在修改或可能正在修改另一个线程时访问该对象。您的var a = new Date("2018-04-17T07:00:00.000Z");
var b = new Date("2018-04-27T07:00:00.000Z");
var dayDif = (a - b) / 1000 / 60 / 60 / 24;
和wait
函数在调用signal
的线程可能正在访问它的同时,通过修改{{1}中的semaphore
(在signal
中)违反了此规则。您也可以使用wait
进行此操作。
如果您在counter
和signal
中所做的事情是合法的,则不需要wait
和signal
。您可以直接访问队列,就像直接访问wait
一样。如果队列需要保护(正如我希望您知道的那样),那么semaphore
也需要保护,原因也完全相同。
允许编译器优化此代码:
semaphore
此代码:
while(semaphore<=0);
为什么?因为它知道没有其他线程可以修改if (semaphore<=0) { while (1); }
,而该线程却可以访问它,因为该标准禁止这样做。因此,没有必要多次阅读。
您需要使用实际的符号和/或锁。