Home > Archive > Unix Programming > November 2004 > Need Help with semaphores
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Need Help with semaphores
|
|
|
| Hi,
Can someone please, explain to me why the following code fails.
In short, I am receiving message: "ERROR: 'unlock' invalid semcnt=0"
So I thought that I probably have a race condition here and decided to
add the second synchronization to protect semcnt (I've added zLock()
and zUnlock()).
However, after that it just deadlocks.
I am not very proficient with concurrent programming and semaphores.
I am on Solaris 9.
variables:
semcnt, semaphore, z_sem are private member variables
int wmsCache::unlock()
{
int rc;
if (zLock()) {perror("ERROR: zLock() failed in unlock()\n");
return -1;}
if (semcnt > 1)
{
semcnt--;
return 0;
}
if (semcnt <= 0)
{
perror("ERROR: 'unlock' invalid semcnt=%d\n", semcnt);
if (zUnlock())
perror("ERROR: zUnlock() failed in unlock()\n");
return -1;
}
struct sembuf buf;
buf.sem_num = 0;
buf.sem_op = 1;
buf.sem_flg = SEM_UNDO;
rc = semop(semaphore, &buf, 1);
if (rc == -1)
{
perror("ERROR: problems unlocking semphore\n");
if (zUnlock())
perror("ERROR: zUnlock() failed in unlock()\n");
return -1;
}
semcnt--;
if (zUnlock()){dbg("ERROR: zUnlock() failed in unlock()\n");
return -1;}
return rc;
}
int wmsCache::lock()
{
int rc;
struct sembuf buf;
if (zLock()){perror("ERROR: zLock() failed in unlock()\n"); return
-1;}
if (semcnt > 0)
{
semcnt++;
return 0;
}
if (semcnt < 0)
{
perror("ERROR: 'lock' invalid semcnt=%d\n", semcnt);
if (zUnlock())
perror("ERROR: zUnlock() failed in unlock()\n");
return -1;
}
buf.sem_num = 0;
buf.sem_op = -1;
buf.sem_flg = SEM_UNDO;
for(rc = semop(semaphore, &buf, 1);
(rc < 0) && (errno == EINTR);
rc = semop(semaphore, &buf, 1))
{
if (rc == -1)
{
perror("ERROR: problems locking semphore\n");
if (zUnlock())
perror("ERROR: zUnlock() failed in unlock()\n");
return -1;
}
}
semcnt++;
if (zUnlock()){perror("ERROR: zUnlock() failed in unlock()\n");
return -1;}
return rc;
}
int wmsCache::zUnlock()
{
int rc;
struct sembuf zBuf;
zBuf.sem_num = 0;
zBuf.sem_op = 1;
zBuf.sem_flg = SEM_UNDO;
rc = semop(z_sem, &zBuf, 1);
if (rc == -1)
{
perror("ERROR: problems unlocking semphore in zUnlock()\n");
return -1;
}
return rc;
}
int wmsCache::zLock()
{
int rc;
struct sembuf zBuf;
zBuf.sem_num = 0;
zBuf.sem_op = -1;
zBuf.sem_flg = SEM_UNDO;
for(rc = semop(z_sem, &zBuf, 1);
(rc < 0) && (errno == EINTR);
rc = semop(z_sem, &zBuf, 1))
{
if (rc == -1)
{
perror("ERROR: problems locking semphore in zLock()\n");
return -1;
}
}
return rc;
}
| |
| Joe Seigh 2004-11-19, 8:57 pm |
|
Zack wrote:
>
> Hi,
>
> Can someone please, explain to me why the following code fails.
> In short, I am receiving message: "ERROR: 'unlock' invalid semcnt=0"
> So I thought that I probably have a race condition here and decided to
> add the second synchronization to protect semcnt (I've added zLock()
> and zUnlock()).
> However, after that it just deadlocks.
> I am not very proficient with concurrent programming and semaphores.
> I am on Solaris 9.
What is semcnt? If it's initlized to zero then it should go to zero
on the last unlock.
And yes you do need a lock to protect incrementing and decrementing semcnt
sonce those aren't atomic.
Also SEM_UNDO is a bad idea. Your shared resource and semcnt will be left
in an undefined state.
Joe Seigh
| |
|
| Joe Seigh <jseigh_01@xemaps.com> wrote in message news:<419E5EFD.25C4E612@xemaps.com>...
> Zack wrote:
>
> What is semcnt? If it's initlized to zero then it should go to zero
> on the last unlock.
>
> And yes you do need a lock to protect incrementing and decrementing semcnt
> sonce those aren't atomic.
>
> Also SEM_UNDO is a bad idea. Your shared resource and semcnt will be left
> in an undefined state.
>
> Joe Seigh
Thanks a bunch for the hint, Joe.
The problem was that I forgot to release the z_sem in unlock()/lock()
in
if (semcnt > 1)
{
semcnt--;
// Now I put zUnlock() in here
return 0;
}
and
if (semcnt > 0)
{
semcnt++;
// Now I put zUnlock() in here
return 0;
}
However, here is another thing that was actually the original problem,
which
I was trying to fix but this modification did not quite get it.
Please bear with me on this.
I have a sort of server application that listens for events and
process them according to their type. For every event that the server
catches I create a POSIX thread, so those events can be processed
concurrently.
Those events are triggered by separate programs/processes. Now, the
server and those programs share the same shared library that
implements cache object where I have the synchronization that I've
already shown in this code.
The problem is that it works while the number of threads on the server
do not exceed 60-70.
After these magic numbers are passed, I experience a deadlock on the
processes that trigger events -- all of them hang on semop. In this
situation if I kill those processes, and restart some of them, so that
number of threads in the server do not exceed 60-70 the programs run
fine. Can some one give me an idea what can be wrong. I can't find
any deadlock situation in the code (Of course it does not mean that
there aren't any).
Any help is VERY appreciated
| |
| Pascal Bourguignon 2004-11-23, 3:58 pm |
| uzmargov@yahoo.com (Zack) writes:
> The problem is that it works while the number of threads on the server
> do not exceed 60-70.
> After these magic numbers are passed, I experience a deadlock on the
> processes that trigger events -- all of them hang on semop. In this
> situation if I kill those processes, and restart some of them, so that
> number of threads in the server do not exceed 60-70 the programs run
> fine. Can some one give me an idea what can be wrong. I can't find
> any deadlock situation in the code (Of course it does not mean that
> there aren't any).
What about : man semop
man semctl
man semget ?
Pay special attention to occurences of "SEMMNI" or "SEMMNS".
--
__Pascal Bourguignon__ http://www.informatimago.com/
The world will now reboot; don't bother saving your artefacts.
|
|
|
|
|