Semaphores

I am getting a strange problem.

I have 3 files,
1. Semaphore.h - Header file
2. Semaphore.cpp - Implementation
3. main.cpp - To test the implementation.

But I am not getting the desired result. Can someone tell me the problem with it.

Semaphore.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <sys/types.h>
#include <sys/sem.h>
class Semaphore
{
private:
    key_t key;
    int nSems;
    struct sembuf sb;
    int semid;

    int initSem();

public:
    Semaphore(int);

    void getLock();

    void ReleaseLock();
};


Semaphore.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include "Semaphore.h"
    
#define MAX_RETRIES 10
    
union semun
{  
    int val;
    struct semid_ds *buf;
    ushort *array;
};  
    
Semaphore::Semaphore(int nsems)
{
    nSems = nsems;
    sb.sem_num = 0;
    sb.sem_op = -1;
    sb.sem_flg = SEM_UNDO;

    if((key = ftok("Semaphore.h", 'R')) == -1)
    {   
        perror("ftok");
        exit(1);
    }

    initSem();
}

int Semaphore::initSem()
{
    int i;
    union semun arg;
    struct semid_ds buf;
    struct sembuf sb;

    semid = semget(key, nSems, IPC_CREAT | IPC_EXCL | 0666);

    if(semid >= 0)
    {  
        sb.sem_op = 1;
        sb.sem_flg = 0;
        arg.val = 1;

        for(sb.sem_num = 0; sb.sem_num < nSems; sb.sem_num++)
        {  
            if(semop(semid, &sb, 1) == -1)
            {  
                int e = errno;
                semctl(semid, 0, IPC_RMID);
                errno = e;
                return -1;
            }
        }
    }
    else if(errno == EEXIST)
    {  
        int ready = 0;

        semid = semget(key, nSems, 0);

        if(semid < 0)
            return semid;

        arg.buf = &buf;

        for(i = 0; i < MAX_RETRIES && !ready; i++)
        {  
            semctl(semid, nSems - 1, IPC_STAT, arg);
            if(arg.buf->sem_otime != 0)
            {
                ready = 1;
            }
            else
            {  
                sleep(1);
            }
        }
        if(!ready)
        {  
            errno = ETIME;
            return -1;
        }
    }
    else
    {  
        return semid;
    }

    return semid;
}

void Semaphore::getLock()
{
    if(semop(semid, &sb, 1) == -1)
    {  
        perror("semop");
        exit(1);
    }
}

void Semaphore::ReleaseLock()
{
    sb.sem_op = 1;

    if(semop(semid, &sb, 1) == -1)
    {  
        perror("semop");
        exit(1);
    }
}


main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include "Semaphore.h"

using namespace std;
int main()
{
    int i;
    Semaphore *sem;

    sem = new Semaphore(1);

    for(i = 0; i < 1000; i++)
    {  
        sem->getLock();
        cout<<"I have the lock:%"<<getpid()<<endl;
        sem->ReleaseLock();
    }

    return 0;
}


I am running 3 executables at the same time. Hence, ideally there should be 3000 print statments. But I am not getting the same. On each run, it is different. It seems it is not working. Can someone point out what the problem is?

Thank you.
Was not sure which forum it belongs to exactly. So posted both the places... :S
Was missing sem_op = -1 in getLock(); Its working fine now. :)

Thanks.
Topic archived. No new replies allowed.