Semaphores

I wanted to a model where many processes trying to access an array. So, I was thinking of making this array in shared memory and then using a semaphore to incorporate mutual exclusion. But what I am wondering is that, since semaphores have only binary values, do they really work with more than 2 processes??
Yes. It works
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.
Updation of sem_op = -1; was missing in getLock(). Its working fine now.

Thanks. :)
Hi,

I am new to this UNIX/Linux (actually i dont have any directions )
can you suggest me what material to refer to in order to study systems programming under UNIX/Linux. ( C/C++ )
also what approach to follow for the same ?


also if you know of any sites for projects C/C++ linux/UNIX please let me know.
can you suggest me what material to refer to in order to study systems programming under UNIX/Linux. ( C/C++ )
also what approach to follow for the same ?

If you need to look up a particular function, refer to the man pages (e.g. use Google to search http://linux.die.net/ ).
To find out which function(s) you need for a particular task, use Google.
how is richard stevens for beginners ... any other book that would be a great refernce for C programming (relevant to systems programming ... x86 intel)

also what is std C/C++ (ANSI etc etc ) lang used in industry ???
Topic archived. No new replies allowed.