线程同步和使用Pthread定义原子块
Thread synchronization and define atomic block using Pthread
我在使用 Pthread 编写 C 语言时遇到了一些问题。
有两个线程(Reader,Main)和共享资源,fd
。
fd
可以通过使用 read_blocking()
和 write_blocking()
以 阻塞方式 访问
我的意图是在需要的时候在主线程中写入数据;有免费的运行 Reader 线程。我使用 Pthread 组件(信号量、互斥锁等)来实现它;但是遇到同步问题,死锁.
下面是针对这种情况的简化代码。
Reader 主题 (free-运行):
// Read data from `fd`
// (Separated thread other than main thread)
void ReaderThread() {
while ( 1 ) {
// [A]
wait_write_complete(g_lock);
// [!] "main thread" should NOT cut into here
read_blocking(fd); // [B]
}
}
Writer 函数(从主线程调用):
// Write data to `fd`
// Called from "main thread"
void WriteData() {
lock(g_lock);
// At this point, the ReaderThread() shoule be @ [A] or [B]
cancel_read(); // force terminate read_blocking()
write_blocking(fd);
unlock(g_lock);
}
[重点]
read_blocking()
和 write_blocking()
应该 NOT 在另一个阻塞时被调用
read_blocking()
可以通过调用 cancel_read()
强制终止
[要求]
- 没有忙等待
- 没有
sleep()
WriteData()
的优先级高于 ReaderThread()
(read_blocking()
应在调用 WriteData() 时取消)
如何防止WriteData()
在wait_write_complete(g_lock)
和read_blocking(fd)
之间中断(标记为[!]的位置)?
wait_write_complete(g_lock)
和 read_blocking(fd)
应该是原子块
什么类型的锁定机制适合g_lock
?
(信号量、互斥锁、屏障、条件等待或任何其他?)
示例代码将非常有用!! :)
我倾向于同意@EOF 的观点,即您描述的通信模式似乎过于复杂。然而,就目前的问题而言, MUTual EXclusion lock 是一种自然的同步机制,用于排除一个线程在两个或两个线程之间采取行动由不同线程执行的更多操作。这可能意味着要实现您的目标,wait_write_complete()
必须在 returns 之前锁定 g_lock
,并且 read_blocking()
必须在函数进入后立即解锁它。
请注意,您需要格外小心,避免简单地将竞争条件移至 read_blocking()
。如何避免这种情况取决于您打算使用中断该函数执行的机制。
此外,我怀疑您需要一个共享标志来指示写入是否挂起/reader 是否可以读取(所有访问都受同一个互斥锁保护),以及一个条件变量暂停 reader 的执行,直到编写器完成。使用这些,wait_write_complete()
可能看起来像这样:
int wait_write_complete(pthread_mutex_t *g_lock) {
int result = pthread_mutex_lock(g_lock);
while (!result && !may_read) {
result = pthread_cond_wait(&read_write_cv, &g_lock);
}
// Note: if this function returns a failure code then the state of the mutex is unknown
return result;
}
编写器线程负责在互斥锁的保护下适当地操作may_read
,并在(重新)启用读取时向条件变量发送信号。
我在使用 Pthread 编写 C 语言时遇到了一些问题。
有两个线程(Reader,Main)和共享资源,fd
。
fd
可以通过使用 read_blocking()
和 write_blocking()
我的意图是在需要的时候在主线程中写入数据;有免费的运行 Reader 线程。我使用 Pthread 组件(信号量、互斥锁等)来实现它;但是遇到同步问题,死锁.
下面是针对这种情况的简化代码。
Reader 主题 (free-运行):
// Read data from `fd`
// (Separated thread other than main thread)
void ReaderThread() {
while ( 1 ) {
// [A]
wait_write_complete(g_lock);
// [!] "main thread" should NOT cut into here
read_blocking(fd); // [B]
}
}
Writer 函数(从主线程调用):
// Write data to `fd`
// Called from "main thread"
void WriteData() {
lock(g_lock);
// At this point, the ReaderThread() shoule be @ [A] or [B]
cancel_read(); // force terminate read_blocking()
write_blocking(fd);
unlock(g_lock);
}
[重点]
read_blocking()
和write_blocking()
应该 NOT 在另一个阻塞时被调用read_blocking()
可以通过调用cancel_read()
强制终止
[要求]
- 没有忙等待
- 没有
sleep()
WriteData()
的优先级高于ReaderThread()
(read_blocking()
应在调用 WriteData() 时取消)
如何防止
WriteData()
在wait_write_complete(g_lock)
和read_blocking(fd)
之间中断(标记为[!]的位置)?wait_write_complete(g_lock)
和read_blocking(fd)
应该是原子块
什么类型的锁定机制适合
g_lock
? (信号量、互斥锁、屏障、条件等待或任何其他?)示例代码将非常有用!! :)
我倾向于同意@EOF 的观点,即您描述的通信模式似乎过于复杂。然而,就目前的问题而言, MUTual EXclusion lock 是一种自然的同步机制,用于排除一个线程在两个或两个线程之间采取行动由不同线程执行的更多操作。这可能意味着要实现您的目标,wait_write_complete()
必须在 returns 之前锁定 g_lock
,并且 read_blocking()
必须在函数进入后立即解锁它。
请注意,您需要格外小心,避免简单地将竞争条件移至 read_blocking()
。如何避免这种情况取决于您打算使用中断该函数执行的机制。
此外,我怀疑您需要一个共享标志来指示写入是否挂起/reader 是否可以读取(所有访问都受同一个互斥锁保护),以及一个条件变量暂停 reader 的执行,直到编写器完成。使用这些,wait_write_complete()
可能看起来像这样:
int wait_write_complete(pthread_mutex_t *g_lock) {
int result = pthread_mutex_lock(g_lock);
while (!result && !may_read) {
result = pthread_cond_wait(&read_write_cv, &g_lock);
}
// Note: if this function returns a failure code then the state of the mutex is unknown
return result;
}
编写器线程负责在互斥锁的保护下适当地操作may_read
,并在(重新)启用读取时向条件变量发送信号。