调用trylock()后解锁互斥锁

时间:2014-11-19 00:39:51

标签: c linux pthreads mutex

我有一个线程服务器,可以添加/附加/读取文件并将数据中继到客户端。

如果正在添加文件,则没有其他线程可以追加/读取它。如果正在追加文件,则没有线程可以追加/读取它。如果正在读取文件,则不会有任何其他线程附加到该文件。但是,如果正在读取文件,则其他文件可以读取它。

目前我有一个互斥系统可以执行此操作,但不允许多次读取。

要解决此问题,在read方法中,我将更改:

pthread_mutex_lock(&(fm->mutex));//LOCK
//do some things`
...
pthread_mutex_unlock(&(fm->mutex));

pthread_mutex_trylock(&(fm->mutex));//TRYLOCK [NonBlocking, so the thread can continue the read]
//do some things`
...
pthread_mutex_unlock(&(fm->mutex));

问题

如何解锁文件而不允许其他方法(只是真正附加)在所有其他read()完成之前开始写入文件?

示例

例如,如果最初锁定文件的读取线程完成并解锁文件,并且还有其他线程尝试读取该文件,则附加线程有机会锁定该文件并开始追加,而其他线程则是还在阅读,这是禁忌。

我想保留当前正在读取文件的线程数。线程完成后,减少计数。如果计数为0,表示没有线程仍在读取,则解锁文件。但是,我担心这不会是线程安全的。如果这是一个可行的解决方案,我怎么能让它的线程安全?另一个但是,我相信只有原始线程才能成功解锁互斥锁。

3 个答案:

答案 0 :(得分:1)

您可以使用信号量而不是互斥量(有关差异,请参阅this link)。信号量为您进行线程安全的同步计数。

如果将同时读取访问的数量限制为(足够大的)数字N并且要求信号量增加该数量以进行写入访问,则可以在没有其他互斥锁的情况下锁定要写入的文件。这样,只有当读者数量为零时才能获得写访问权限,并且所有其他读者将被锁定,直到您的作者完成为止。

答案 1 :(得分:1)

听起来你可能正在寻找由pthreads提供的read-write lock。它允许两种锁定模式:共享/读锁定模式,可以同时被多个线程锁定,以及独占/写锁定模式,其中锁定调用不会返回,直到所有其他线程(读取器)和作家们放弃了锁定。

答案 2 :(得分:0)

请注意pthread_mutex_lock()的POSIX文档说:

  

如果成功, pthread_mutex_lock() pthread_mutex_trylock() pthread_mutex_unlock()函数将返回零;否则,应返回错误编号以指示错误。

由于您没有显示测试返回值的代码,因此您不知道您的锁定操作(特别是)是否成功。

另外,既然你想要一个读/写锁,为什么不使用一个:

有四个pthread_rwlockattr_*()个函数和总共9个pthread_rwlock_*()函数;我只列出了家庭中最重要的功能。