我的任务是使用posix pthreads创建一个读者 - 作者问题的解决方案。我产生了3位读者和1位作家。
任务规范要求一次向队列2添加值(写入者)。读者一次出列一个队列(当队列中存在值时)。队列已经过测试并且有效。
我遇到的问题是在运行程序时,它导致大多数时间只有1个读取器线程实际读取。有时重复执行将导致使用所有3个读者。但大多数时候它只使用了1个读者。我不确定为什么会出现这种奇怪的行为。
提前致谢。
Expected (Sometimes):
TID: -684419328
TID: -684419328
TID: -673929472
TID: -673929472
TID: -694909184
TID: -694909184
...
Actual (Sometimes):
TID: -684419328
TID: -684419328
TID: -684419328
TID: -684419328
TID: -684419328
TID: -684419328
...
pthread_cond_t qServiced = PTHREAD_COND_INITIALIZER;
pthread_cond_t qElement = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
#include "rw.h"
#include "queue.h"
queue* q;
void* reader()
{
int serviced = 0;
int x;
while(!fin)
{
pthread_mutex_lock(&mutex);
counter++;
while(isEmpty(q))
{
pthread_cond_signal(&qEmpty);
pthread_cond_wait(&qElement, &mutex); e
}
printf("TID: %d\n", (int)pthread_self());
num* n = dequeue(q); //Take one task
printf("Num1: %d\n", n->num1);
printf("Num2: %d\n", n->num2);
serviced++;
pthread_cond_signal(&qServiced); //Signal that task has been serviced
pthread_mutex_unlock(&mutex);
}
}
以下提议的代码仅适用于'read()'线程,但应该让您了解如何编写线程。
void* reader( void *arg )
{
int *fin = (int*)arg;
int serviced = 0;
while( !(*fin) )
{
printf("TID: %d\n", (int)pthread_self());
pthread_mutex_lock(&mutex);
counter++;
num* n = dequeue(q); //Take one task
pthread_mutex_unlock(&mutex);
if( n )
{
printf("Num1: %d\n", n->num1);
printf("Num2: %d\n", n->num2);
serviced++;
}
else
{
printf( "no queue entries available\n" );
sleep(1);
}
}
pthread_exit( NULL );
}
请注意,只有在线程执行可能导致“竞争”条件的操作时,才会锁定互斥锁。
建议的代码假设(因为队列处理代码从未发布),如果队列为空,dequeue()
返回NULL
注意:当没有可用的队列条目时,线程会休眠一段时间
这假设main()函数在调用pthread_create()
时将'fin'的地址作为参数传递
线程由调度程序在一个调度机制中调度。但作为一名程序员,你应该假设它可以是任何随机的方式和代码。
通过说“随机方式”,我的意思是所有线程都可以在程序过程中安排一次,或者在整个过程中只安排一个线程。
线程可能以随机方式进行调度。我希望这回答了你的问题。
如果您想要一种特定的执行方式(例如:所有线程在第二次读取线程之前读取一次),那么您必须相应地进行编码。您可以使用互斥锁,信号量,条件信号,标志以及所有这些的组合来实现此目的。