Skip Menu |

This queue is for tickets about the IPC-Semaphore-Concurrency CPAN distribution.

Report information
The Basics
Id: 79313
Status: rejected
Priority: 0/
Queue: IPC-Semaphore-Concurrency

People
Owner: DERMOTH [...] cpan.org
Requestors: NHORNE [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 0.02
Fixed in: (no value)



Subject: Locking inconsistency
This program works once, but if you run it straight away again the message 'parent acuired' appears immediately instead of after 3 seconds. #!/usr/bin/perl -w use strict; use warnings; use IPC::Semaphore::Concurrency; if(fork()) { # parent; sleep(3); my $lock = IPC::Semaphore::Concurrency->new(path => $0); # This should fail, but actually it succeeds $lock->acquire(wait => 1); print "parent acquired\n"; $lock->release(); exit(); } my $lock = IPC::Semaphore::Concurrency->new(path => $0); $lock->acquire(wait => 1); print "child acquired\n"; sleep(10); $lock->release(); print "child freed\n"; sleep(10);
I didn't mean this: Show quoted text
>appears immediately instead of after 3 seconds.
I meant it appears after 3 seconds instead of after 10. What I'm saying here is that acquire() doesn't wait except for the first time yo u run the program.
Hi, I don't see any issue here. After the fork you have *two independent processes* racing for the same lock, and the order at which this lock is granted depends on various external factors. If you want to guarantee the locking order you must acquire the lock in the parent *before* forking, then in the child you can create another semaphore and get a lock. Only then the order will be predictable. Something like this has the desired behaviour: #!/usr/bin/perl -w use strict; use warnings; use IPC::Semaphore::Concurrency; my $p_lock = IPC::Semaphore::Concurrency->new(path => $0); $p_lock->acquire(wait => 1); if(fork()) { # parent; print "parent acquired\n"; sleep(3); $p_lock->release(); exit(); } # Forked child; $p_lock isn't safe to use here... undef $p_lock; my $c_lock = IPC::Semaphore::Concurrency->new(path => $0); $c_lock->acquire(wait => 1); print "child acquired\n"; sleep(10); $c_lock->release(); print "child freed\n"; sleep(10); I will close the bug in a few days if you have no further questions or comments. Thanks
Subject: Re: [rt.cpan.org #79313] Locking inconsistency
Date: Fri, 31 Aug 2012 09:35:05 +0100
To: bug-IPC-Semaphore-Concurrency [...] rt.cpan.org
From: Nigel Horne <njh [...] bandsman.co.uk>
Thanks for your reply. Show quoted text
> I don't see any issue here. After the fork you have *two independent > processes* racing for the same lock, and the order at which this lock is > granted depends on various external factors.
Indeed I have two independent processes going for the same lock. That's by design - that's what locks are for. -Nigel
So, as I said, if you need to guarantee a certain order you need get your locks in the correct order. Note that you could do more that just locks with a plain semaphore object, which may help working around your specific issue; this module is only a very simple interface on top of IPC::Semaphore to use it as a lock. I'm closing this bug as "rejected" as there really isn't anything for me to fix. Thanks
Subject: Re: [rt.cpan.org #79313] Locking inconsistency
Date: Sat, 18 Jan 2014 01:21:13 -0500
To: bug-IPC-Semaphore-Concurrency [...] rt.cpan.org
From: Thomas Guyot-Sionnest <dermoth [...] aei.ca>
On 31/08/12 04:35 AM, njh@bandsman.co.uk via RT wrote: Show quoted text
> Queue: IPC-Semaphore-Concurrency > Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=79313 > > > Thanks for your reply. >
>> I don't see any issue here. After the fork you have *two independent >> processes* racing for the same lock, and the order at which this lock is >> granted depends on various external factors.
> > Indeed I have two independent processes going for the same lock. That's > by design - that's what locks are for. > > -Nigel > > >
Hi Nigel, I looked into it and the problem is that you call release() without doing an "undo => 0"in acquire(); the semaphore, which is merely a shared counter, is incremented a 2nd time at process exit. This means at every run your semaphore end up with two more than the initial value (1) and needs as many "locks" (aka running processes holding the lock) to prevent other processes from using it. I agree the doc should be a lot clearer on the risks and implications of using release() - it was added only for completeness as the initial use case was letting the lock be released with the death of the process. Regards, -- Thomas