我有一个线程服务器,可以添加/附加/读取文件并将数据中继到客户端。
如果正在添加文件,则没有其他线程可以追加/读取它。如果正在追加文件,则没有线程可以追加/读取它。如果正在读取文件,则不会有任何其他线程附加到该文件。但是,如果正在读取文件,则其他文件可以读取它。
目前我有一个互斥系统可以执行此操作,但不允许多次读取。
要解决此问题,在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,表示没有线程仍在读取,则解锁文件。但是,我担心这不会是线程安全的。如果这是一个可行的解决方案,我怎么能让它的线程安全?另一个但是,我相信只有原始线程才能成功解锁互斥锁。
答案 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_rwlock_rdlock()
pthread_rwlock_wrlock()
pthread_rwlock_unlock()
pthread_rwlock_init()
pthread_rwlock_destroy()
有四个pthread_rwlockattr_*()
个函数和总共9个pthread_rwlock_*()
函数;我只列出了家庭中最重要的功能。