Reputation: 41
I am trying to do a program with semaphore and fork and shared memory
the parent suppose to create the shared memory and insert numbers to the buffer print done then the child going to read from shared memory and print the sum of the numbers the program run but only the parent print done but the child does not do any thing,
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdio.h>
#include <netinet/in.h>
#include <netdb.h>
#include<netinet/in.h>
#include<netdb.h>
#include<sys/wait.h>
#include<unistd.h>
#include <sys/shm.h>
char buffer[10];
char *data;
int commNo =0;
key_t key;
int shmid;
char *shrmem;
int mode;
void error(char *msg)
{
perror(msg);
exit(0);
}
int rem[10];
key_t key; /* key to pass to semget() */
key_t key1; /* key to pass to semget() */
key_t key2; /* key to pass to semget() */
key_t key3; /* key to pass to semget() */
int semflg; /* semflg to pass tosemget() */
int nsems; /* nsems to pass to semget() */
int semid; /* return value from semget() */
#define MAX_COUNT 200
#define N 100 /* shared buffer of size 100 */
void ChildProcess(void); /* child process prototype */
void ParentProcess(void); /* parent process prototype */
//things for ftok
char *path = "/tmp";
int id = 'S';
//create sembuf
//struct sembuf{
// ushort sem_num; /* semaphore index in array */
// short sem_op; /* semaphore operation */
// short sem_flg; /* operation flags */
//};
int locksem = 1; /* binary semaphore for locking-unlocking: initiall unlocked : 1 */
int emptysem = 100; /* counting semaphore for empty slots */
int fullsem = 0; /* counting semaphore for filled slots*/
struct sembuf oplock;// = (struct sembuf *) malloc(2*sizeof(struct sembuf));
//static struct sembuf oplock;
//oplock.sem_num = 0;
//oplock.sem_op = -1;
//oplock.sem_flg = SEM_UNDO;
struct sembuf opunlock; // = (struct sembuf *) malloc(2*sizeof(struct sembuf));
//static struct sembuf opunlock;
//opunlock.sem_num = 0;
//opunlock.sem_op = 1;
//opunlock.sem_flg = SEM_UNDO;
void creatmemory(){
/* make the key: */
if ((key = ftok("/tmp",1)) == -1) {
perror("ftok");
//clientnumber
exit(1);
}
/* connect to (and possibly create) the segment: */
if ((shmid = shmget(key, 15, 0644| IPC_CREAT)) == -1) {
perror("shmget");
exit(1);
}
/* attach to the segment to get a pointer to it: */
data = shmat(shmid, (void *)0, 0);
if (data == (char *)(-1)) {
perror("shmat");
exit(1);
}
}
int main(int argc, char *argv[]){
pid_t pid;
nsems = 1;
//static struct sembuf oplock;
oplock.sem_num = 0;
oplock.sem_op = -1;
oplock.sem_flg = SEM_UNDO;
//static struct sembuf opunlock;
opunlock.sem_num = 0;
opunlock.sem_op = 1;
opunlock.sem_flg = SEM_UNDO;
//to create new one
semflg = IPC_CREAT;
/* Get unique key for semaphore. */
if ((key1 = ftok(path,1)) == (key_t) -1) {
perror("IPC error: ftok"); exit(1);
}
/* Get unique key for semaphore. */
if ((key2 = ftok(path,2)) == (key_t) -1) {
perror("IPC error: ftok"); exit(1);
}
/* Get unique key for semaphore. */
if ((key3 = ftok(path,3)) == (key_t) -1) {
perror("IPC error: ftok"); exit(1);
}
pid = fork();
if (pid == 0) {
//***************************************************************************************************************
//
int n =0;
while(n < 3){
locksem = semget(key1, nsems, semflg); /* open-create locksem*/
emptysem = semget(key2, nsems, semflg);
fullsem = semget(key3, nsems, semflg);
semop(fullsem,&oplock,1); /* check filled slots */
semop(locksem,&oplock,1); /* lock shared buffer*/
// itx= remove_item();
/* remove an item from buffer */
int i;
for (i =0; i<10; i++){
rem[i] = data[i];}
bzero(buffer,10);
bzero(data,strlen(data));
/* detach from the segment: */
if (shmdt(data) == -1) {
perror("shmdt");
exit(1);
}
semop(locksem,&opunlock,1); /* unlock the buffer */
semop(emptysem,&opunlock,1); /* increment emptysem*/
//consume_item(itx);
int sum = 0;
for(i =0; i<10; i++){
sum += rem[i];}
printf("the sum is:%d \n", sum);
n++;}
}
//consumer();
else
{
creatmemory();
int n =0;
while( n < 3) {
locksem = semget(key1, nsems, semflg); /* open-create locksem*/
emptysem = semget(key2, nsems, semflg);
fullsem = semget(key3, nsems, semflg);
bzero(buffer,10);
int i;
for(i =0; i<10; i++)
buffer[i] = i;
semop(emptysem,&oplock,1); /* check empty slots */
semop(locksem,&oplock,1); /* lock shared buffer*/
/* insert item into the buffer */
strncpy(data, buffer, strlen(buffer));
printf("done \n");
semop(locksem,&opunlock,1); /* unlock the buffer */
semop(fullsem,&opunlock,1); /* increment fullsem*/
sleep(10);
n++;}
}
// producer();
}
Upvotes: 0
Views: 830
Reputation: 16540
Here is a version of the code that actually compiles and links cleanly:
#define _XOPEN_SOURCE (1) // needed by sys/ipc.h
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdio.h>
#include <stdlib.h> // exit()
#include <string.h>
#include <strings.h> // bzero())
#include <netinet/in.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/shm.h>
char buffer[10];
char *data;
int commNo =0;
key_t key;
int shmid;
char *shrmem;
int mode;
void error(char *);
int rem[10];
key_t key; /* key to pass to semget() */
key_t key1; /* key to pass to semget() */
key_t key2; /* key to pass to semget() */
key_t key3; /* key to pass to semget() */
int semflg; /* semflg to pass tosemget() */
int nsems; /* nsems to pass to semget() */
int semid; /* return value from semget() */
#define MAX_COUNT 200
#define N 100 /* shared buffer of size 100 */
void creatmemory( void );
//things for ftok
char *path = "/tmp";
int id = 'S';
//create sembuf
//struct sembuf{
// ushort sem_num; /* semaphore index in array */
// short sem_op; /* semaphore operation */
// short sem_flg; /* operation flags */
//};
int locksem = 1; /* binary semaphore for locking-unlocking: initiall unlocked : 1 */
int emptysem = 100; /* counting semaphore for empty slots */
int fullsem = 0; /* counting semaphore for filled slots*/
struct sembuf oplock;// = (struct sembuf *) malloc(2*sizeof(struct sembuf));
//static struct sembuf oplock;
//oplock.sem_num = 0;
//oplock.sem_op = -1;
//oplock.sem_flg = SEM_UNDO;
struct sembuf opunlock; // = (struct sembuf *) malloc(2*sizeof(struct sembuf));
//static struct sembuf opunlock;
//opunlock.sem_num = 0;
//opunlock.sem_op = 1;
//opunlock.sem_flg = SEM_UNDO;
int main()
{
pid_t pid;
nsems = 1;
//static struct sembuf oplock;
oplock.sem_num = 0;
oplock.sem_op = -1;
oplock.sem_flg = SEM_UNDO;
//static struct sembuf opunlock;
opunlock.sem_num = 0;
opunlock.sem_op = 1;
opunlock.sem_flg = SEM_UNDO;
//to create new one
semflg = IPC_CREAT;
/* Get unique key for semaphore. */
if ((key1 = ftok(path,1)) == (key_t) -1) {
perror("IPC error: ftok"); exit(1);
}
/* Get unique key for semaphore. */
if ((key2 = ftok(path,2)) == (key_t) -1) {
perror("IPC error: ftok"); exit(1);
}
/* Get unique key for semaphore. */
if ((key3 = ftok(path,3)) == (key_t) -1) {
perror("IPC error: ftok"); exit(1);
}
if( 0 == (pid = fork() ) )
{ // then, child process
int n =0;
for(;n<3;n++)
{
locksem = semget(key1, nsems, semflg); /* open-create locksem*/
emptysem = semget(key2, nsems, semflg);
fullsem = semget(key3, nsems, semflg);
semop(fullsem,&oplock,1); /* check filled slots */
semop(locksem,&oplock,1); /* lock shared buffer*/
// itx= remove_item();
/* remove an item from buffer */
int i = 0;
for (;i<10; i++)
{
rem[i] = data[i];
} // end for
bzero(buffer,10);
bzero(data,strlen(data));
/* detach from the segment: */
if (shmdt(data) == -1)
{
error( "shmdt" );
} // error() does not return
// implied else, shmdt successful
semop(locksem,&opunlock,1); /* unlock the buffer */
semop(emptysem,&opunlock,1); /* increment emptysem*/
//consume_item(itx);
int sum = 0;
for(i =0; i<10; i++)
{
sum += rem[i];
} // end for
printf("the sum is:%d \n", sum);
} // end while
}
else
{ // else parent process
creatmemory();
int n =0;
for(;n<3;n++)
{
locksem = semget(key1, nsems, semflg); /* open-create locksem*/
emptysem = semget(key2, nsems, semflg);
fullsem = semget(key3, nsems, semflg);
bzero(buffer,10);
int i;
for(i =0; i<10; i++)
{
buffer[i] = i;
} // end for
semop(emptysem,&oplock,1); /* check empty slots */
semop(locksem,&oplock,1); /* lock shared buffer*/
/* insert item into the buffer */
strncpy(data, buffer, strlen(buffer));
printf("done \n");
semop(locksem,&opunlock,1); /* unlock the buffer */
semop(fullsem,&opunlock,1); /* increment fullsem*/
sleep(10);
} // end for
} // end if
return(0);
} // end function: main
void creatmemory()
{
/* make the key: */
if ((key = ftok("/tmp",1)) == -1)
{
error( "ftok" ); // error does not return
}
// implied else, ftok successful
/* connect to (and possibly create) the segment: */
if ((shmid = shmget(key, 15, 0644| IPC_CREAT)) == -1)
{
error( "shmget" ); // error does not return
}
// implied else, shmget successful
/* attach to the segment to get a pointer to it: */
data = shmat(shmid, (void *)0, 0);
if (data == (char *)(-1))
{
error( "shmat" ); // error does not return
}
// implied else, shmat successful
} // end function: creatmemory
void error(char *msg)
{
perror(msg);
exit(0);
} // end function: error
I would suggest using a mutex rather than a semaphore for critical code/data protection.
BTW: unless destroyed, a semaphore is around forever.
In Linux, they become part of the /proc directory tree.
Upvotes: 2