【发布时间】:2015-01-16 09:16:27
【问题描述】:
我有一个线程服务器,可以添加/附加/读取文件并将数据中继到客户端。
如果正在添加文件,则没有其他线程可以附加/读取它。如果正在附加文件,则没有线程可以附加/读取它。如果正在读取文件,则没有其他线程可以附加到它。但是,如果一个文件正在被读取,其他文件可以读取它。
目前我有一个互斥系统可以执行此操作,但它不允许多次读取。
为了解决这个问题,我将在 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,表示没有线程仍在读取,则解锁文件。但是,我担心这不是线程安全的。如果这是一个可行的解决方案,我怎样才能使它成为线程安全的?另一个但是,我相信只有原始线程才能成功解锁互斥锁。
【问题讨论】:
-
听起来你可能正在寻找一个读写锁,由pthreads提供:docs.oracle.com/cd/E19455-01/806-5257/6je9h032t/index.html
-
一个文件可以有多少个状态?在我看来,至少需要三种状态,“已添加”(添加该文件后的状态)、“附加”(添加该文件后的状态”和“读取”(添加该文件后的状态)。一个互斥锁可能不足以控制三个状态。
-
@Fumu Add/Append 本质上是相同的,不应将它们视为单独的状态。只有读取是不同的,所以我想说这里仍然只有两个状态。
-
@JeremyFriesner 那不是 pthread 链接......但现在在 pthreads 中搜索。编辑:哎呀,只是一个例子链接到其他地方,没有使用 pthreads。
-
@JeremyFriesner 如果您愿意,可以将其添加为答案,我现在已经有了工作代码,只需进行很少的更改即可使其运行。谢谢!