Results 1 to 4 of 4
Hello Everybody,
I am building a server. this server contains some data. Clients may modify this data or read this data.
If a client is reading the data and at ...
- 07-21-2011 #1Just Joined!
- Join Date
- Jul 2011
- Posts
- 3
about Semaphores
Hello Everybody,
I am building a server. this server contains some data. Clients may modify this data or read this data.
If a client is reading the data and at the same time another client is modifying the data then at this case the reading client may read some false data (some old mixed with some new). So i used Semaphores to solve this problem so when any one is reading or writing he stops if another one is reading or writing.
but there is a small problem. i just want to prevent a reader from reading if there is someone writing. and prevent a writer from writing if there is another one writing. but i don't want to prevent a reader from reading if there is someone is also reading ! ..
cases i want to prevent : a reader requests reading and another one is writing , a writer requests writing and another one is writing , a writer requests writing and another one is reading. but a reader requests reading and another one is reading i don't want to prevent it.
how can i manage this using semaphores or any other tool ?
Thanks in advance
- 07-21-2011 #2Linux Guru
- Join Date
- Apr 2009
- Location
- I can be found either 40 miles west of Chicago, or in a galaxy far, far away.
- Posts
- 8,974
This is a finite state machine type of problem. You absolutely don't want multiple writers at the same time, so writers need to get a mutex lock on the data - use a separate thread for this. When a writer gets a lock, it can copy the data to a private buffer, modify it, update a volatile update variable, and then update the actual data when there are no readers (using the access count variable). The readers can atomically update (increment/decrement) an access access count (volatile) variable, and verify that the update variable is not set before it reads the data. There are a lot of possibilities for race conditions, which is why you need an FSM (finite state machine) to verify that this cannot occur. Not simple - pretty much the rocket science of software engineering...

Myself, I use a control thread to handle this. A reader or writer thread will send a message to the control thread, and it won't be released until the operation it wants can be performed safely. IE, multiple readers are immediately released to read the data, and when done send a "finished" message to the control thread, but if a writer tries while there are unfinished readers or writers, it is held, or likewise a reader will be held if there is an active writer. This method simplifies things since you don't have to deal with semaphores or mutexes, and only throttles read performance when there is a write operation in progress. The control thread can also provide a FIFO queue functionality to ensure fairness of access.Sometimes, real fast is almost as good as real time.
Just remember, Semper Gumbi - always be flexible!
- 07-22-2011 #3Linux Newbie
- Join Date
- Nov 2008
- Location
- Tokyo, Japan
- Posts
- 243
When old and new data get mixed up, we computer scientists call this a "race condition", as in, the two threads were in a race to finish their task first, and crashed into each other. We computer scientists call this a "deadlock".
The most difficult task in programming multi-threaded (concurrency) applications is preventing deadlocks and race conditions. Programming languages like Java have special syntax that help prevent race conditions. If you are using C, you need to be a bit more careful. Rubberman's suggestion was good.
- 07-22-2011 #4
I don't believe that the set of cases that Omar is trying to prevent involves deadlocks. A deadlock is when two threads are each waiting on the other to finish. Omar is simply listing the situations that his concurrency solution should prevent.
The simplest way of doing this would probably be to harness file locking, which directly model this.
A file can be locked with the flock() function. There are two types of locks:
A shared lock (aka "read lock") may exist in parallel with other shared locks. These are commonly obtained by a reader on a file before reading. If an exclusive lock exists on the file, attempting to lock will block until no exclusive locks are held.
An exclusive lock (aka "write lock") may be the only lock on a file. These are commonly used by writers on a file. If any other lock exists, attempting to lock will block.
So you see, this is basically the exact situation that you are talking about.
So, you could have your threads lock on some file in the filesystem (/tmp/datalock or something). They must acquire a lock on this file before they perform any operation on the data in the system.DISTRO=Arch
Registered Linux User #388732


Reply With Quote
