所以,我正在尝试在C中实现并发队列。我已将方法拆分为“读取方法”和“写入方法”。因此,当访问write方法(如push()和pop())时,我获取了一个写入器锁。对于读取方法也是如此。此外,我们可以有几个读者,但只有一个作家。
为了让它在代码中工作,我有一个整个队列的互斥锁。还有两个条件锁 - 一个用于作者,另一个用于读者。我还有两个整数来跟踪当前使用队列的读者和作者的数量。
所以我的主要问题是 - 如何实现多个读者同时访问读取方法?
目前这是我的一般读取方法代码:(在伪代码中 - 而不是C.我实际上正在使用pthreads。)
mutex.lock();
while (nwriter > 0) {
wait(&reader);
mutex.unlock();
}
nreader++;
//Critical code
nreader--;
if (nreader == 0) {
signal(&writer)
}
mutex.unlock
所以,想象一下,我们有一个持有互斥锁的读者。现在任何其他读者,并尝试获取互斥锁,将无法。不会阻止吗?那么许多读者如何同时访问读取方法呢?
我的推理是否正确?如果是,如何解决问题?
答案 0 :(得分:2)
如果不是练习,请使用pthreads(pthread_rwlock_*
函数)的读写锁。
另请注意,使用lock stil保护单个调用可能无法提供必要的正确性保证。例如,从STL队列中弹出元素的典型代码是
if( !queue.empty() ) {
data = queue.top();
queue.pop();
}
即使在队列方法中使用了锁,这也会在并发代码中失败,因为从概念上讲,此代码必须是原子事务,但实现不提供此类保证。线程可以弹出与top()读取的元素不同的元素,或尝试从空队列等弹出
答案 1 :(得分:1)
请找到以下读/写功能。
在我的函数中,我使用了canRead和canWrite互斥体和nReads来获取读者数量:
写功能:
lock(canWrite) // Wait if mutex if not free
// Write
unlock(canWrite)
阅读功能:
lock(canRead) // This mutex protect the nReaders
nReaders++ // Init value should be 0 (no readers)
if (nReaders == 1) // No other readers
{
lock(canWrite) // No writers can enter critical section
}
unlock(canRead)
// Read
lock(canRead)
nReaders--;
if (nReaders == 0) // No more readers
{
unlock(canWrite) // Writer can enter critical secion
}
unlock(canRead)
答案 2 :(得分:0)
经典的解决方案是多读者,单一作家。
数据结构始于没有读者和没有作者。
您允许任意数量的并发读者。
当一位作家出现时,你阻止他直到所有现在的读者完成;那么你就让他走了(任何新的读者和作家都会按顺序在他身后排队。)
答案 3 :(得分:0)
您可以尝试使用内置于c本机,无锁,适用于跨平台lfqueue的库
例如:-
int* int_data;
lfqueue_t my_queue;
if (lfqueue_init(&my_queue) == -1)
return -1;
/** Wrap This scope in other threads **/
int_data = (int*) malloc(sizeof(int));
assert(int_data != NULL);
*int_data = i++;
/*Enqueue*/
while (lfqueue_enq(&my_queue, int_data) == -1) {
printf("ENQ Full ?\n");
}
/** Wrap This scope in other threads **/
/*Dequeue*/
while ( (int_data = lfqueue_deq(&my_queue)) == NULL) {
printf("DEQ EMPTY ..\n");
}
// printf("%d\n", *(int*) int_data );
free(int_data);
/** End **/
lfqueue_destroy(&my_queue);