Deadlock in dining philosophers with channels from Ben Ari? - concurrency

In Ben Ari's Principles of Concurrent and Distributed Programming (2nd ed.), chapter 8.4, The dining philosophers with channels, they propose a solution which I think might lead to deadlock.
Suppose a philosopher 3 takes fork 3. The philosopher must then take the 4th fork to eat. But the 4th fork might be taken by the 4th philosopher.
As a generalization, each philosopher might take first the fork 'on his left', resulting in each of them waiting for the other fork to be released, which will never be able to occur.
Am I missing something, or is this solution incomplete?
In the chapter about semaphores, something similar happens, but the authors propose an alternative solution which mitigates the deadlock scenario. For example, one could add a restriction so one philosopher first takes the fork on the opposite side of which the others do, thus avoiding deadlock. I think this might be a possible solution, but I'd like to confirm with someone else here.
Thanks in advance!

Am I missing something, or is this solution incomplete?
I was definitely not missing anything: I confirmed with the professor teaching this book at my university that this solution does indeed lead to deadlock.

Related

Is deadlock possible in this case?

There are four resourses of the same type, and three processes. Each process needs 2 resourses at most. Is a deadlock possible?.
I have read some similar examples which say that once process will have 2 resourses and can run to completion, and then release those resourses, and so on. So in that way deadlock is impossible.
But my teacher insist that is a deadlock scenario, and i am not convinced with his answer.
what is the true answer?

An imaginary lock mechanism: non-blocking write, read and invalidate

Here is the scenario. Bob is a writer and Alice is a reader. Bob writes things and Alice reads them. The rules are:
1) Bob can write whether Alice is reading or not (reading does not block writes).
2) When Bob is writing, Alice cannot read (writing does block reads).
3) When Alice finishes reading, she can know if Bob wrote during her read (readers can detect if the data they just read is not valid).
2) and 3) are really one combined rule, but I list two for good discussion. The problem can be solved by one mutex and one counter (version number), but what I do not know is, is the above a well-know scenario with a commonly used name? Has any research been done on it?
Which I do not know is, is the problem a well-know scenario named by terms?
Yes, it is called Seqlock:
https://en.wikipedia.org/wiki/Seqlock
Does anyone study at it or I am just making a wheel?
AFAIK there are a variety of implementation (such as Linux kernel) and papers.

C++ TBB concurrent_bounded_queue - pop timeout

I noticed that TBB concurrent_bounded_queue blocking pop has no timeout. We are moving to TBB from another implementation where we had timed wait and hence looking for the same functionalities here.
In any case, it's often useful to have timed-wait, any suggestion will be appreciated.
Thanks
According to Arch Robinson, the architect of TBB, timeouts were never a priority:
The initial design of TBB targeted a paradigm of task-based programming for parallel speedup. It is what I think of as "classical" parallel algorithms like parallel_for, parallel_reduce, etc.The containers and mutexes were designed with that in mind; i.e., to avoid race conditions.Blocking was expected to be short, otherwise the program would not scale. Therefore timeouts were not a priority.
There's an old article where one of the TBB engineers discusses timed mutexes. You probably won't be able to use the workaround sketched there directly, but it can help you implement a blocking dequeue yourself, basing it off on concurrent_queue's not blocking try_pop.
I wouldn't expect the performance to be anywhere near that of just using the TBB queues, and it won't be that trivial (probably 100+ LOC), but if you really want it, it can be done.
P.S. Java BlockingQueue-style blocking poll/offer with a timeout is something that you probably don't want to be using on your fast paths. A couple of times I have started an implementation with such a method, only to find after some period of time (no pun intended), that either producer/consumer pressure is not enough and just blocking is at least as efficient, or I need to investigate what happens and rethink some part of my code.

Is db_query thread safe?

I am working with MySQL in C++. I had an issue before with mysql_query() not being thread safe (http://dev.mysql.com/doc/refman/5.1/en/c-api-threaded-clients.html.) Is db_query() any different or do the rules in the first bullet point from the doc I linked to apply to db_query() too? I assume they operate the same, but I want to make sure it isn't slightly different and end up unlocking my mutex too quickly or leave it locked longer than necessary. Sorry I couldn't find any documentation specifically on this issue for db_query().
Thanks.
Sorry everyone, I didn't realize that this db_query() was imported from another file. I'm still learning the code base :/ No wonder I couldn't find any documentation on it! Sorry to whomever's time I wasted.
...And it isn't thread safe. It is just a wrapper for mysql_query() doh XD

Read write mutex in C++

This is an interview question. How do you implement a read/write mutex? There will be multiple threads reading and writing to a resource. I'm not sure how to go about it. If there's any information needed, please let me know.
Update: I'm not sure if my statement above is valid/understandable. But what I really want to know is how do you implement multiple read and multiple writes on a single object in terms of mutex and other synchronization objects needed?
Check out Dekker's algorithm.
Dekker's algorithm is the first known
correct solution to the mutual
exclusion problem in concurrent
programming. The solution is
attributed to Dutch mathematician Th.
J. Dekker by Edsger W. Dijkstra in his
manuscript on cooperating sequential
processes. It allows two threads to
share a single-use resource without
conflict, using only shared memory for
communication.
Note that Dekker's algorithm uses a spinlock (not a busy waiting) technique.
(Th. J. Dekker's solution, mentioned by E. W. Dijkstra in his EWD1303 paper)
The short answer is that it is surprisingly difficult to roll your own read/write lock. It's very easy to miss a very subtle timing problem that could result in deadlock, two threads both thinking they have an "exclusive" lock, etc.
In a nutshell, you need to keep a count of how many readers are active at any particular time. Only when the number of active readers is zero, should you grant a thread write access. There are some design choices as to whether readers or writers are given priority. (Often, you want to give writers the priority, on the assumption that writing is done less frequently.) The (surprisingly) tricky part is to ensure that no writer is given access when there are readers, or vice versa.
There is an excellent MSDN article, "Compound Win32 Synchronization Objects" that takes you through the creation of a reader/writer lock. It starts simple, then grows more complicated to handle all the corner cases. One thing that stood out was that they showed a sample that looked perfectly good-- then they would explain why it wouldn't actually work. Had they not pointed out the problems, you might have never noticed. Well worth a read.
Hope this is helpful.
This sounds like an rather difficult question for an interview; I would not "implement" a read/write mutex, in the sense of writing one from scratch--there are much better off-the-shelf solutions available. The sensible real world thing would be to use an existing mutex type. Perhaps what they really wanted to know was how you would use such a type?
Afaik you need either an atomic compare-and-swap instruction, or you need to be able to disable interrupts. See Compare-and-swap on wikipedia. At least, that's how an OS would implement it. If you have an operating system, stand on it's shoulders, and use an existing library (boost for example).