LinuxQuestions.org
Visit Jeremy's Blog.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 08-24-2004, 03:08 PM   #1
beginner_84
LQ Newbie
 
Registered: Aug 2004
Posts: 11

Rep: Reputation: 0
semaphore


This program creates a circular queue of integers of size 20 in shared memory. It then creates 4 child processes. The second, third, and the fourth process created enters 50 consecutive integers each starting from 100, 200, and 300 respectively (so the second process enters 100, 101, 102,…,149; the third process enters 200, 201, 202, ..249 and so on). The first process sums up the integers entered and prints the final sum after all the integers have been entered and summed up.
The parent process waits until all child processes finish, cleans up all the shared memory and semaphore created, and exits.

HOWEVER, the program is not behaving in the expected manner..... the problem arises when the queue becomes full..
CAN ANYONE HELP ME OUT?... its urgent !!

Code:
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <errno.h>

#define P(s) semop(s, &pop, 1)
#define V(s) semop(s, &vop, 1)

int queue_is_empty(int z)
{
  if(z==0)
    return 1;
  else return 0;
}
int queue_is_full(int z)
{
  if(z==20)
    return 1;
  else return 0;
}
int insert(int a[],int number,int *indexs,int *size)
{
  if(*indexs==20)
    *indexs=0;
  a[(*indexs)++]=number;
  (*size)++;
  printf("%d\n",number);
  getchar();
  return 1;
}
int removes(int a[],int *indexs,int *size)
{
  if(*indexs==0)
    *indexs=20;
  (*size)--;
  printf("%d\n",a[(*indexs)-1]);
  getchar();  
  return a[--(*indexs)];
}

int main()
{
  int shmid,status;
  int semid1,semid2,semid3,semid4,sum=0,count=50,count1; 
  struct sembuf pop,vop;
  int *sto1,*sto2,*sto3,*sto4;
  int semparent,i,j;
  pid_t pid[4];

  shmid = shmget(IPC_PRIVATE, 22*sizeof(int), 0777|IPC_CREAT); 
  semid1 = semget(IPC_PRIVATE, 1, 0777|IPC_CREAT);
  semid2 = semget(IPC_PRIVATE, 1, 0777|IPC_CREAT);
  semid3 = semget(IPC_PRIVATE, 1, 0777|IPC_CREAT);
  semid4 = semget(IPC_PRIVATE, 1, 0777|IPC_CREAT);
  
  semctl(semid1, 0, SETVAL, 0);
  semctl(semid2, 0, SETVAL, 1);
  semctl(semid3, 0, SETVAL, 0);
  semctl(semid4, 0, SETVAL, 0);
 
  pop.sem_num = vop.sem_num = 0;
  pop.sem_flg = vop.sem_flg = 0;
  pop.sem_op = -1 ; vop.sem_op = 1 ;
  
  if(fork() == 0)
    {
      sto1 = (int *) shmat(shmid, 0, 0);      
      P(semid1);
      
      sto1[20]=0;
      sto1[21]=0;
    
      while (count1) {
	if(queue_is_empty(sto1[20]))
	  {
	    V(semid2);
	    P(semid1);
	  }
      	else
	  { 
	    printf("Process1 :");
	    //getchar();
	    sum+=removes(sto1,&sto1[21],&sto1[20]);
	    count1--;
	  }
      }
      shmdt(sto1);
      printf("SUM :%d\n",sum);
      getchar();
      exit(0);
    }
  else if(fork() ==0)
    {
      printf("\nentering 2");
      sto2 = (int *) shmat(shmid, 0, 0);
      //P(semid3);
      //P(semid4);
      while(count)
	{
	  P(semid2);
     
	  if(queue_is_full(sto2[20]))
	    {	  
	      V(semid1);
	      P(semid2);
	    }
	  else
	    {
	      printf("Process2 :");
	 
	      insert(sto2,count+100,&sto2[21],&sto2[20]);
	      count--;
	 	
	    }
	  printf("2nd"); 
	  V(semid3);
      
	}
      shmdt(sto2);
      exit(0);
    }

  else if(fork() ==0)
    {
      sto3 = (int *) shmat(shmid, 0, 0);
 
      while(count)
	{
	  P(semid3);
	  // P(semid2);
	  //   P(semid4);
	  if(queue_is_full(sto3[20]))
	    {	  printf("\nFull");
	    V(semid1);
	    P(semid3);
	    }
	  else
	    {
	      printf("Process3 :");
	      //getchar();
	      insert(sto3,count+200,&sto3[21],&sto3[20]);
	      count--;
	    }
	  printf("nunua");
	  V(semid4);
      
	}
      shmdt(sto3);
      exit(0);
    }
  else if(fork() ==0)
    {
      sto2 = (int *) shmat(shmid, 0, 0);
  
      while(count)
	{
	  printf("\nhug me");
	  P(semid4);
	  if(queue_is_full(sto2[20]))
	    {	  
	      printf("hagga");
	      V(semid1);
	      P(semid4);
	    }
	  else
	    {
	      printf("Process4 :");
	      //getchar();
	      insert(sto2,count+300,&sto2[21],&sto2[20]);
	      count--;
	    }
	 
	  V(semid2);
      
	}
      shmdt(sto4);
      exit(0);
    }
  else
    {
      sleep(3);
      wait(&status);
      shmctl(shmid, IPC_RMID, 0);
      semctl(semid1, 0, IPC_RMID, 0);
      semctl(semid2, 0, IPC_RMID, 0);
      semctl(semid3, 0, IPC_RMID, 0);
      semctl(semid4, 0, IPC_RMID, 0);
      
    }
}
 
Old 08-24-2004, 05:14 PM   #2
acid_kewpie
Moderator
 
Registered: Jun 2001
Location: UK
Distribution: Gentoo, RHEL, Fedora, Centos
Posts: 43,417

Rep: Reputation: 1985Reputation: 1985Reputation: 1985Reputation: 1985Reputation: 1985Reputation: 1985Reputation: 1985Reputation: 1985Reputation: 1985Reputation: 1985Reputation: 1985
this question looks an awful lot like homework. lpease note that it is against LQ rules to request help for homework, and if this is indeed some sort of assignment / coursework i'd be grateful if you could remove the content yourself.
 
Old 08-25-2004, 06:22 PM   #3
beginner_84
LQ Newbie
 
Registered: Aug 2004
Posts: 11

Original Poster
Rep: Reputation: 0
this is not a homework but a program that i encountered myself during learning semaphores and shared memory....... i have written the whole code myself but i m puzzled to see that its not working.so thats y I'd b grateful if any one of u can plz have a look and point out the problem....
 
Old 08-25-2004, 06:33 PM   #4
itsme86
Senior Member
 
Registered: Jan 2004
Location: Oregon, USA
Distribution: Slackware
Posts: 1,246

Rep: Reputation: 59
I'd recommend starting smaller. Maybe just 1 child. See if simplifying the problem leads you to a solution. If you can get it to work with 1 child, then try 2 children before jumping to 5.
 
Old 08-25-2004, 06:52 PM   #5
beginner_84
LQ Newbie
 
Registered: Aug 2004
Posts: 11

Original Poster
Rep: Reputation: 0
i have worked successfully with 1 and 2 child processes......... in this program, the queue takes input perfectly for first 20 entries but after that instead of emptying the queue, the program goes to child2 and then the problem starts....data are taken in random order from the children after that.
 
Old 08-25-2004, 06:54 PM   #6
beginner_84
LQ Newbie
 
Registered: Aug 2004
Posts: 11

Original Poster
Rep: Reputation: 0
one mistake that i have found was taking sto2 again in 4th process in place of sto4. That was a typo.But correcting that hasn't solved the problem .
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
How to test for remaining semaphore? LocalFruit Programming 1 11-25-2005 07:03 AM
difference mutex vs. semaphore? Thinking Programming 1 11-16-2005 05:26 AM
Semaphore tzzdvd Programming 1 05-24-2005 09:23 PM
about semaphore dummyagain Programming 1 11-11-2003 11:09 AM
Semaphore setting for Redhat 7.0 bgupta Linux - General 1 01-17-2003 11:04 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 04:08 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration