UNIX Socket FAQ

A forum for questions and answers about network programming on Linux and all other Unix-like systems

You are not logged in.

#1 2008-07-24 10:05 AM

frank2004
Member
From: Beijing
Registered: 2004-07-20
Posts: 93

Re: System V semphore and shared memory

Hello,there
here is my code about semphore, I used it to protect the shared memory.But sometimes it makes the shared memory bad, but I can not find it, anyone can point some bugs and give some suggestion?

#define  BIGCOUNT  	888      // initial value of process counter 
#define  SEM_POST_LIMIT 3	


int sem_create_V(char *semfilepath, int seminterval , char semprojectid) 
{
  key_t 	key ;
  int 		semid ;
  int 		fileId;
  FILE          *fp;


  if ((fp = fopen (semfilepath,"wb")) == NULL )
    {
       perror("fopen");
       return -1;
      }
   fclose (fp);
 
  if ( (key = ftok(semfilepath , semprojectid)) < 0 )
       {
         perror("ftok");
         return -1;
       }

  if ( (semid = Sem_Create(key,seminterval)) < 0 )
        return -1;

  return semid ;
}




int Sem_Create(key_t key,int intval)
{

 int id,semval;
 union semnum{
      int val;
      struct semid_ds *buf;
      ushort *array;
    } semctl_arg;

  op_lock[0].sem_num = 2;
  op_lock[0].sem_op = 0;
  op_lock[0].sem_flg = 0;
  op_lock[1].sem_num = 2;
  op_lock[1].sem_op = 1;
  op_lock[1].sem_flg = 0;

  op_endcreate[0].sem_num = 1;
  op_endcreate[0].sem_op = -1;
  op_endcreate[0].sem_flg = 0;

  op_endcreate[1].sem_num = 2;
  op_endcreate[1].sem_op = -1;
  op_endcreate[1].sem_flg = 0;


  if (key== IPC_PRIVATE)
        return -1;
  
   else
     if (key == (key_t)-1)
        return -1;

     if ((id=semget(key,3,0666|IPC_CREAT))<0)
    // if ((id=semget(key,3,IPC_CREAT))<0)
       {
         perror("semget create");
         return -1;
       }


 again:;
     if (semop(id,&op_lock[0],2)<0) { 
         if (errno== EINVAL)
           goto again;
        perror("semop create");
        return -1; 
     }



   // get the value of the process counter,if it equal 0,then no one has initialize the semaphore
 
   if ((semval =semctl(id,1,GETVAL,0)) <0)
     {
        perror("semctl create GETVAL");
        return -1; 
     }

   if (semval == 0) {
     semctl_arg.val = intval;
     if ( semctl(id,0,SETVAL,semctl_arg) < 0) 
      {
        perror("semctl create SETVAL");
        return -1; 
      }
     semctl_arg.val = BIGCOUNT;
     
     if (semctl(id,1,SETVAL,semctl_arg) < 0)
      {
        perror("semctl create SETVAL");
        return -1;
      }
    }
  
    if (semop(id,&op_endcreate[0],2) < 0)
      {
        perror("semop create");
        return -1; 
      }
    return id;
}


int sem_wait_V(int id, struct sembuf  *sem_pv)
{


  sem_pv = new struct sembuf [1] ;

  if (sem_op(id,-1, sem_pv)<0)
    {
     // perror("sem_op waiting");
//     printf("sem_wait_V: %d,%d !\n",id,errno) ;
     delete sem_pv ;
     return -1;
    }

  delete sem_pv ;
 


  return 0;
}






int sem_post_V(int id, int sem_post_value_V, struct sembuf  *sem_pv)
{

 if ((sem_post_value_V = semctl(id,0,GETVAL,0)) <0)
	{
       	return -1; 
     	}
 if( sem_post_value_V > SEM_POST_LIMIT )
	{
	if( sem_post_value_V == SEM_POST_LIMIT + 1 )	return -1 ;
	return -1 ;
	}

 sem_pv = new struct sembuf [1] ; 
 
 if (sem_op(id,1,sem_pv)<0)
    {
     delete sem_pv ;
     return -1;
    }

 delete sem_pv ;

 return 0;
}

int sem_op(int id,int value, struct sembuf sem_pv1[1] )
{
  int sem_value ,sem_value1; 


   struct sembuf sem_pv[1];
  sem_pv[0].sem_num = 0 ;
     sem_pv[0].sem_flg = 0 ;

  if ((sem_pv[0].sem_op =value) == 0)
	{
	printf("sem_op error: operator is zero !!!!!!!(%d)\n",id) ;
        return -1;
	}

if ((sem_value = semctl(id,0,GETVAL,0)) <0)
     		{
        	perror("semctl create GETVAL");
                return -1;
     		}

 again:;
  if (semop(id,&sem_pv[0],1)<0)
        {
         sched_yield() ;
         if(errno==EINTR) 
          {
                	if ((sem_value1 = semctl(id,0,GETVAL,0)) <0)
     	                	{
        	                   perror("semctl create GETVAL");
                                   return -1;
     		                }
                           else
                             {
                                 if (sem_value != sem_value1 )
                                     return -1;
                                  else
                                     goto again;
                            }
           }
         return -1;
        }    

  return  1;

}

Offline

Board footer

Powered by FluxBB