Are there ways to implement named process internal mutexes using C/C++ (in Unix/Linux)?
The trick is that the mutexes lifetime would need to be process persistent. Unlike for example the named posix semaphores and shared memory.
You could have for example pthread mutexes, in a dynamic map and access them with some id. But then you need to protect the mutexes somehow.
If you use memory mapped files or shared memory, you get the filesystem persistence...
Any ideas?
You can always revert back to the older (albeit depreciated) System V semaphores which work off a common key-value rather than a POSIX named semaphore which has file-system persistence. That being said, a POSIX named semaphore will not have file-system persistence if you close and then unlink the semaphore in every process using it. Once the last process that was using the semaphore has exited, the semaphore reference will be removed from the file-system. If you're worried about the visibility of the semaphore at the file-system level, you can always precede the name of the semaphore with a "." in order to make the file invisible, and/or adjust the permissions on the file so that only the current user or some privileged user/group can access the semaphore.
What do you mean by "process-persistent"? If you want them to persist after the process ends, just use named semaphores or named shared memory, and prefix the name with something unique to your program. If you want them to go out of existence when the process terminates, just use any kind of hash map protected by an rwlock (locked in read mode to lookup existing names, write mode to add/remove names).
It's quite simple. Have a mapping of strings to mutexes, and a mutex to protect this mapping:
std::map<std::string, pthread_mutex_t *> mutexMap;
pthread_mutex_t mutexMap_lock = PTHREAD_MUTEX_INITIALIZER;
When you need to find a mutex, take the mutexMap_lock lock first. Once you have the mutex, drop the lock, and cache the mutex pointer so you don't have to keep referring to this mutexMap point of contention.
Related
I have to write a daemon to decide acces policy for mutexes ( it establishes which process get the mutex if more than one want the same mutex on whatever criteria)
For that I established some codes : L 1 231 (LOCK mtx_id process_pid).
When a process requests a mutex it writes on a shared memory zone some code similar to the one above.
The daemon reads it. (For every mutex I have a queue with processe waiting to get it.) Puts the process pid in queue.
If it is unlocked , pop queue, give mutex.( Write in shared memory id_mutex and process of the pid that got it, for other processes to read and know who has the mutex.
My question is : how do more processe request same mutex ? Creating them at first and selecting the requested process manually does not seem such a good option.
Any help is appreciated.THank you
Many OS have a container, a catalog, directory or registry, of OS objects that can be stored by name. Once stored in the container, they can be looked up by name and a reference token returned. That token can then be used to access the object.
A synchro object like an inter-process mutex would be a good candidate for storage in the container. Multiple processes could then look up the mutex by name and use it.
Such cataloged objects are often reference-counted so that they are only destroyed when the last process with a token calls for it to be closed.
BTW - see comments, your design suc.... has issues :(
I am programming in C++ in Linux and I am using pthreads library. I am using mutex to protect some shared variables but I am not sure if in this specific case it is necessary the use of mutex.
I have 3 threads. The shared variable is a string (global variable).
Thread1 changes it's value and afterwards, thread2 and thread3 read it's value and store in another string.
In this case, the string's value is only modified by one thread. Is still necessary the use of mutex to protect a shared variable in a concurrent read by two threads?
"Thread1 changes it's value and afterwards ..." -- if "afterwards" means that the other threads are created after the change, there's no need for a mutex; thread creation synchronizes memory. If it means anything else then you need some form of synchronization, in part because "afterwards" in different threads is meaningless without synchronization.
What you should use is a shared_mutex (get it from boost if you don't want to use C++14/17) (for C++14 there's a shared_timed_mutex that you could use). Then, you do a shared_lock if you want to read the string, and you do a unique_lock if you want to write on it.
If two shared locks meet, they don't collide and they don't block, but a shared lock and a unique lock collide and one of the locks blocks until the other finishes.
Since you are using pthreads, you can use a pthread_rwlock_t.
For updating the object, it would be locked using pthread_rwlock_wrlock() to get a write lock; all readers would access the object only after obtaining a shared read lock with pthread_rwlock_rdlock(). Since the write lock is exclusive, and the read lock is shared, you'd get the behavior you desire.
An example of the use of pthread_rwlock_t read/write locks can be found at http://www.ibm.com/support/knowledgecenter/ssw_aix_71/com.ibm.aix.genprogc/using_readwrite_locks.htm.
A good summary of the available calls for use on a pthread_rwlock_t lock can be found at https://docs.oracle.com/cd/E19455-01/806-5257/6je9h032u/index.html. I've reproduced the table listing the operations:
Operation
Initialize a read-write lock "pthread_rwlock_init(3THR)"
Read lock on read-write lock "pthread_rwlock_rdlock(3THR)"
Read lock with a nonblocking read-write lock "pthread_rwlock_tryrdlock(3THR)"
Write lock on read-write lock "pthread_rwlock_wrlock(3THR)"
Write lock with a nonblocking read-write lock "pthread_rwlock_trywrlock(3THR)"
Unlock a read-write lock "pthread_rwlock_unlock(3THR)"
Destroy a read-write lock "pthread_rwlock_destroy(3THR)"
I am new to threading . Correct me if I am wrong that mutex locks the access to a shared data structure so that it cannot be used by other threads until it is unlocked . So, lets consider that there are 2 or more shared data structures . So , should I make different mutex objects for different data structures ? If no ,then how std::mutex will know which object it should lock ? What If I have to lock more than 1 objects at the same time ?
There are several points in your question that can be made more precise. Perhaps clearing this will solve things for you.
To begin with, a mutex, by itself, does not lock access to anything. It is basically something that your code can lock and unlock, and some "magic" ensures that only one thread can lock it at a time.
If, by convention, you decide that any code accessing some data structure foo will first begin by locking a mutex foo_mutex, then it will have the effect of protecting this data structure.
So, having said that, regarding your questions:
It depends on whether the two data structures need to be accessed together or not (e.g., can updating one without the other leave the system in an inconsistent state). If so, you should lock them with a single mutex. If not, you can improve parallelism by using two.
The mutex does not lock anything. It is you who decide by convention whether you can access 1, 2, or a million data structures, while holding it.
If you always needs to access both structures then it could be considered as a single resource so only a single lock is needed.
If you sometimes, even just once, need to access one of the structures independently then they can no longer be considered a single resource and you might need two locks. Of course, a single lock could still be sufficient, but then that lock would lock both resources at once, prohibiting other threads from accessing any of the structures.
Mutex does not "know" anything other than about itself. The lock is performed on mutex itself.
If there are two objects (or pieces of code) that need synchronized access (but can be accessed at the same time) then you have the liberty to use just one mutex for both or one for each. If you use one mutex they will not be accessed at the same time from two different threads.
If it cannot happen that access to one object is required while accessing the other object then you can use two mutexes, one for each. But if it can happen that one object must be accessed while the thread already holds another mutex then care must be taken that code never can reach a deadlock, where two threads hold one mutex each, and both at the same time wait that the other mutex is released.
I am looking for the best way to effectively share chunks of data between two (or more) processes in a writer-biased reader/writer model.
My current tests are with boost::interprocess. I have created some managed_shared_memory and am attempting to lock access to the data chunk by using an interprocess mutex stored in the shared memory.
However, even when using sharable_lock on the reader and upgradable_lock on the writer, the client will read fragmented values during write operations instead of blocking. While doing a similar reader/writer setup between threads in a single process, I used upgrade_to_unique_lock to solve this issue. However, I have not found its boost::interprocess equivalent. Does one exist?
Server (writer):
while (1) {
// Get upgrade lock on the mutex
upgradable_lock <MutexType> lock(myMutex);
// Need 'upgrade_to_unique_lock' here so shared readers will block until
// write operation is finished.
// Write values here
}
Client (reader)
while (1)
{
// Get shared access
sharable_lock <MutexType> lock(myMutex);
// Read p1's data here -- occasionally invalid!
}
I guess the bigger question at hand is this: is an interprocess mutex even the proper way to access shared memory between processes in a writer-biased setup?
Note: using Boost 1.44.0
All Boost.Interprocess upgradable locks support upgrade per this. Definition here.
Regarding your broader question - I would think that this is precisely what you want. Readers can still work concurrently, and you have to prevent concurrent writes. Unless you can partition the shared memory such that more constrained access is guaranteed, this looks the best.
Solution by OP.
The answer, as stated in the question comments is to use the member function unlock_upgradable_and_lock. If there is an boost::interprocess analog to upgrade_to_unique_lock, I don't know where it is. But the writer() function can be rewritten as:
while (1) {
// Get upgrade lock on the mutex
myMutex.lock_upgradable();
// Get exclusive access and block everyone else
myMutex.unlock_upgradable_and_lock();
// Write values here
// Unlock the mutex (and stop blocking readers)
myMutex.unlock();
}
What is the difference between event objects and condition variables?
I am asking in context of WIN32 API.
Event objects are kernel-level objects. They can be shared across process boundaries, and are supported on all Windows OS versions. They can be used as their own standalone locks to shared resources, if desired. Since they are kernel objects, the OS has limitations on the number of available events that can be allocated at a time.
Condition Variables are user-level objects. They cannot be shared across process boundaries, and are only supported on Vista/2008 and later. They do not act as their own locks, but require a separate lock to be associated with them, such as a critical section. Since they are user- objects, the number of available variables is limited by available memory. When a Conditional Variable is put to sleep, it automatically releases the specified lock object so another thread can acquire it. When the Conditional Variable wakes up, it automatically re-acquires the specified lock object again.
In terms of functionality, think of a Conditional Variable as a logical combination of two objects working together - a keyed event and a lock object. When the Condition Variable is put to sleep, it resets the event, releases the lock, waits for the event to be signaled, and then re-acquires the lock. For instance, if you use a critical section as the lock object, SleepConditionalVariableCS() is similar to a sequence of calls to ResetEvent(), LeaveCriticalSection(), WaitForSingleObject(), and EnterCriticalSection(). Whereas if you use a SRWL as the lock, SleepConditionVariableSRW() is similar to a sequence of calls to ResetEvent(), ReleaseSRWLock...(), WaitForSingleObject(), and AcquireSRWLock...().
They are very similar, but event objects work across process boundaries, whereas condition variables do not. From the MSDN documentation on condition variables:
Condition variables are user-mode
objects that cannot be shared across
processes.
From the MSDN documentation on event objects:
Threads in other processes can open a
handle to an existing event object by
specifying its name in a call to the
OpenEvent function.
The most significant difference is the Event object is a kernel object and can be shared across processes as long as it is alive when processes/threads are trying to acquire, on the contrary, Condition variable is a user mode object which is light(only has same size as a pointer and has nothing additional to be released after using it) and has better performance.
Typically, condition variable is often used along with locks, since we need to keep data synchronized properly. When considering Condition Variable, we treat it like keyed events which was improved since Vista.
Joe duffy has a blog post http://joeduffyblog.com/2006/11/28/windows-keyed-events-critical-sections-and-new-vista-synchronization-features/ that explained more detailed information.