PDA

View Full Version : Interprocess nonblocking semaphore / mutex / shared memory.



m.p
10th May 2011, 11:45
Hello!

I need lock some resources (e.g. files) used by my programs. I've got few process and I want synchronize beetwen them. QSystemSemaphore or QSharedMemory look nice, but unfortunetly those classes don't have non-blocking function to lock (like QMutex's tryLock() ). Could anyone pass me a nice multiplatform solution for that?

best regards
m.p

high_flyer
10th May 2011, 17:05
QSharedMemory look nice, but unfortunetly those classes don't have non-blocking function to lock
QSharedMemory::lock()

m.p
11th May 2011, 10:08
QSharedMemory::lock()

No, no, no. QSharedMemory::lock() is locking function, from doc:

"This is a semaphore that locks the shared memory segment for access by this process and returns true. If another process has locked the segment, this function blocks until the lock is released."

I need something non blocking.

high_flyer
11th May 2011, 10:16
Sorry read to fast.
But you can do it your self.
For example, you can override QSharedMemory so:


// in the header:
bool m_bLocked;

//and
bool isLocked() {return m_bLocked; }


//in the implementation:
//initialize in the ctor

bool MyQSharedMemory::tryLock()
{
if(!m_bLocked){
m_bLocked = QSharedMemory::lock();
return m_bLocked;
}

return false;
}



But I would go through the QSharedMemory doc thoroughly, as my guess is that the trolls didn't build it in in the first place because probably it conflicts with the way QSharedMemory work, and the way it should be used.
Since I didn't work with it yet, I can't say.

Another way is to use to protect the resource with a mutex, and only do something with it if you managed to lock the mutex.


if(mutex.tryLock()){
//Do something with resource
}

m.p
11th May 2011, 11:02
Yours solutions are fine, but not for me. They wont work for more than one process.

high_flyer
11th May 2011, 11:11
What do you mean "more than one process"?
Can you explain a bit more?

m.p
11th May 2011, 14:54
What do you mean "more than one process"?
Can you explain a bit more?

Yes. I have two or more separate application wrote by me (or more than one instance of one app), and the can use common resources (e.g. files), and I want provide exclusive acces at the time to them. So I must synchronize those processes.

high_flyer
11th May 2011, 15:16
One relative easy way of doing this is by creating a temp file, that all sharing applications know about.
If the file exist, the application knows the resource is used by another application.
So you can in your application just use QFileInfo::exists(), to know if other applications are using the resource.
Something like:
1. look if file exist.
2. If exist, continue with something else.
3. if does not exist, create file, and access shared resource.
4. delete file when shared resource when finished dealing with shared resource.

m.p
11th May 2011, 15:19
I have been thinking about that solution, but what if one of process that acquired acces to resources and created temp file crashed before it can delete this temp file? Other proces will be thinking, that resources are loocked.

high_flyer
11th May 2011, 15:28
You can handle that by catching and handling SIGSEGV signal.
You can search in the forum there are several threads about it, or google it.

m.p
12th May 2011, 09:44
SIGSEGV is a POSIX signal. I need multiplatform solution.

high_flyer
12th May 2011, 11:04
Well, then you will just have to implement the segmentation fault catching per system, and guard it with #ifdef <your OS>.
Just few more lines of code.
But any OS should have some sort of signal on segmentation fault, either POSIX or something else.
OR -
On windows, you can for example use exceptions, and raise a SIGSEGV your self, and then you need only one signal handler for POSIX and Windows.
http://msdn.microsoft.com/en-us/library/xdkz3x12%28v=vs.71%29.aspx

The SIGILL, SIGSEGV, and SIGTERM signals are not generated under Windows NT. They are included for ANSI compatibility. Thus you can set signal handlers for these signals with signal, and you can also explicitly generate these signals by calling raise.

m.p
13th May 2011, 12:53
I rather write some os dependend code for mutex (CreateMutex() for Win and pthread for POSIX) than write segfaults handlers...

wysota
13th May 2011, 13:06
Create a protected resource that will determine if the resource you are after is available. Then regular lock() is fine because you only do the locking for a short moment.


class Sync {
public:
Sync(const QString &key) : mem(key){
dat = 0;
if(mem.create(sizeof(bool))) dat = (bool*)mem.data();
else return;
mem.lock();
*dat = true;
mem.unlock();
}
~Sync() { if(dat) mem.detach(); }
bool tryLock() {
mem.lock();
if(*dat) {
/* lock the real resource here */;
*dat = false;
mem.unlock();
return true;
} else { mem.unlock(); return false; }
}
void lock() {
mem.lock();
if(*dat) { /* lock the resource, etc. */ } else {
mem.unlock();
// lock on a QSystemSemaphore
}
}
// unlock in a similar fashion
private:
QSharedMemory mem;
bool *dat;
}

This is ALMOST foul proof.

high_flyer
13th May 2011, 13:08
I rather write some os dependend code for mutex (CreateMutex() for Win and pthread for POSIX) than write segfaults handlers...
The both are not related.
You raised a concern that one application may crash while it holds a resource.
You need to handle that case, no mater what type of locking mechanism you are using, be it deleting a file, or something else.
Google for "inter process communication", and choose the one best fits your needs.
There is nothing in Qt I know of for that, except may DBus but that is not supported on all platforms.

m.p
17th May 2011, 13:15
Create a protected resource that will determine if the resource you are after is available. Then regular lock() is fine because you only do the locking for a short moment.



bool tryLock() {
mem.lock();



if(*dat) {
/* lock the real resource here */;
*dat = false;
mem.unlock();
return true;
} else { mem.unlock(); return false; }
}


This is ALMOST foul proof.

And what about when app will hang up in moment marked as ? Other app will also hangup becouse of blocking nature of lock()...

wysota
17th May 2011, 17:02
Why would it hang here?