PThread RWLock Deadlocking with Recursive Locks

2019-05-31 15:26发布

I've been working on a small sand-boxed example to help me figure out how to use rwlocks. Everything seems fairly straightforward, however I'm getting deadlocks in my example every once and a while and don't understand why it's happening.

I've put the code example on pastebin because it's more than a few lines of code: http://pastebin.org/359203

If you run the example. When it eventually deadlocks the last three print statements will be one of two cases:

one:

th4: request lock
th3: request lock
th4: locked

two:

th3: request lock
th4: request lock
th3: locked

Based on the output. To me it seems like there is an eventual deadlock from a second call to a locking function, whether it's to a read lock, or a write lock. But since one of the threads has the lock, and the same thread is what calls the second locking function, why is it deadlocking? Even more interesting, what is it in this small case that is causing the deadlock?

Note that I'm on Mac OS X, and that this is a seriously contrived example. It's sand-boxed from something else I'm working on and wanted to make sure I get this part right.

5条回答
一夜七次
2楼-- · 2019-05-31 16:09

I posted a workaround for this question in Pthread RWLock on MAC Deadlocking but not on Linux?

It is platform independent, and the general method ought to allow for other tricks like upgrading from read to write, etc.

查看更多
叛逆
3楼-- · 2019-05-31 16:11

Your problem is that pthread_rwlock_wrlock(3) is not reentrant. The documentation clearly states that the results of calling this method when the thread already holds the lock are undefined. Your code specifically calls the method twice without releasing the lock in between.

查看更多
等我变得足够好
4楼-- · 2019-05-31 16:15

pthread_rwlock supports recursive read locking, but not recursive write locking. If you write lock the lock while you already hold it, you have entered the realm of undefined behavior. This is the case for your thfn3().

It's clearer if you call the threads the "reader" (thfn4) and the "writer" (thfn3). Case one is then:

  • reader tries to lock
  • writer tries to lock and blocks waiting for reader to release lock
  • reader gets lock
  • reader tries to lock again and blocks waiting for writer to acquire lock and release lock

In this case, the reader is likely unable to lock again because there is a writer waiting on the lock, and would-be writers block would-be readers.

Case two is:

  • writer tries to lock
  • reader tries to lock and blocks waiting for writer to finish
  • writer gets lock
  • writer tries to lock again and blocks

This case can likely only be explained by appeal to details of the rwlock implementation.

查看更多
smile是对你的礼貌
6楼-- · 2019-05-31 16:28
登录 后发表回答