Проблема в следующем, после 32676 срабатываний блокировки семафора на следующий раз, т. е. 32678 блокировка не работает, semop возвращает ошибку. В чем дело? Понятно, что переполнение short int, а с чего это? Ниже приводятся две программы иллюстрирующие этот случай.
#include <errno.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h>
#include <sys/sem.h>
int Initialize( key_t nSemKey ) { int nStatus = 0, nSemId;
if( (nSemId = semget(nSemKey, 1, IPC_CREAT | IPC_EXCL)) == -1 ) { if( errno = EEXIST ) { nSemId = semget(nSemKey, 1, 0); } } else { union semun Arg; unsigned short asnValues[1] = { 0 }; Arg.paArray = asnValues; semctl(nSemId, 0, SETALL, Arg); }
return nSemId; }
int Destroy( int nId ) { union semun Arg; return semctl(nId, 1, IPC_RMID, Arg); }
int Wait( int nId ) { struct sembuf Operation;
Operation.sem_num = 0; Operation.sem_op = -1; Operation.sem_flg = SEM_UNDO;
nWait++;
return semop(nId, &Operation, 1); }
int Release( int nId ) { struct sembuf Operation;
Operation.sem_num = 0; Operation.sem_op = 1; Operation.sem_flg = SEM_UNDO;
return semop(nId, &Operation, 1); }
//Программа 1 int main(int argc, char *argv[]) { key_t nKey1 = 0x12345; key_t nKey2 = 0x67890;
int nSem1 = Initialize(nKey1); int nSem2 = Initialize(nKey2);
int nError, nCount = 0;
while( nCount < 50000 ) { nError = Wait(nSem1); nError = Release(nSem2);
nCount++;
if( nError == -1 ) { printf("nCount = %d\n", nCount); break; } }
Destroy(nSem1); Destroy(nSem2);
}
//Программа 2 int main(int argc, char *argv[]) { key_t nKey1 = 0x12345; key_t nKey2 = 0x67890;
int nSem1 = Initialize(nKey1); int nSem2 = Initialize(nKey2);
int nError, nCount = 0;
Release(nSem1);
while( nCount < 50000 ) { nError = Wait(nSem2); nError = Release(nSem1);
nCount++;
if( nError == -1 ) { printf("nCount = %d\n", nCount); break; } }
Destroy(nSem1); Destroy(nSem2); return 0; }