Hi everyone:
This is my first attempt on semaphores and threads. I constructed this code from examples and the man pages found on the Net. I have two doubts with this code.
Why do I get a Bus error whenever I try semctl( I know this is the root of the problem because of the debug line 3 does not get printed) and how to prevent it?
Why am I not able to acquire a lock on my critical section inspite of removing semctl()?
I am trying to execute the following code:
#include <stdio.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/sem.h>
#define NUM 3
char c='a';
int semId=-1;
struct sembuf lockOperation = { 0, -1, 0};
struct sembuf unlockOperation = { 0, -1, 0};
void* PrintLetter()
{
int rc;
rc=semop(semId, &lockOperation, 1);
if(rc)
{
printf("\n Unable to lock\n");
exit(1);
}
printf("%c",c); //CRITICAL SECTION
c=c+1; //CRITICAL SECTION
rc = semop(semId, &unlockOperation, 1);
if(rc)
{
printf("\n Unable to unlock\n");
exit(1);
}
pthread_exit(NULL);
}
int main()
{
pthread_t threads[NUM];
int rc=1;
long t;
printf("debug line 1\n");
semId = semget(IPC_PRIVATE, 1, IPC_CREAT|IPC_EXCL);
if( semId == -1)
{
printf("\n Error in making the sem\n");
exit(1);
}
printf("debug line 2\n");
rc = semctl(semId, 0, SETVAL, (int)1); // Comment from here
if(rc)
{
printf("\n Unable to set val to 1\n");
exit(1);
} ////////////////////////////////// till here
printf("debug line 3\n");
for(t=0; t<NUM; t++){
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, PrintLetter, NULL);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
sleep(3);
}
pthread_exit(NULL);
}
NOTE: I added the following to the code after suggestion:
union semun {
int val; /* Value for SETVAL */
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* Array for GETALL, SETALL */
struct seminfo *__buf; /* Buffer for IPC_INFO
(Linux specific) */
};
Also added the following:
union semun s_u;
s_u.val=1;
Changed the semctl line to
rc = semctl(semId, 0, SETVAL, s_u);
and made all rc checks to:
if(rc == -1)
semctl() line still does not execute sucessfully. The errno now states : Permission Denied
UPDATE: I am able to get rid off the "Permission Denied" error using the following change:
semId = semget(IPC_PRIVATE, 1, IPC_CREAT|IPC_EXCL|0660);
Now , the new problem is that, I am unable to print "abc" on the console. The program just prints "a" and hangs. Not sure why.
Final UPDATE: I messed up in the Unlock code: i used -1 instead of 1 Here is the new code:
struct sembuf unlockOperation = { 0, 1, 0};
I thank you all for your help and patience.