2013-03-03 6 views
5

Ho ricevuto l'errore nel seguente programma. Voglio dimostrare come due processi possono condividere una variabile usando il semaforo. Qualcuno può guidarmi?implementazione semaforo

io non sono in grado di eseguire il debug degli errori ...

#include<stdlib.h> 
#include<stdio.h> 
#include<unistd.h> 
#include<sys/ipc.h> 
#include<sys/sem.h> 
#include<semaphore.h> 
int main() 
{ 
    int pid,mutex=1; 
    int semid;    /* semid of semaphore set */ 
    key_t key = 1234; /* key to pass to semget() */ 
    int nsems = 1; /* nsems to pass to semget() */ 
    semid=semget(key,nsems,IPC_CREAT|0666); 
    if (semid<0) 
    { 
    perror("Semaphore creation failed "); 
    } 
    if ((pid = fork()) < 0) 
    { 
    perror("fork"); 
    return 1; 
    } 
    else if(pid==0) 
    { 
    sem_wait(&semid); 
    printf("IN CHILD PROCESS :\n"); 
    mutex++; 
    printf("value of shared variable =%d",mutex); 
    sem_post(&semid); 
    return 0; 
    } 
    sem_wait(&semid); 
    printf("IN PARENT PROCESS :\n"); 
    mutex--; 
    printf("value of shared variable =%d",mutex); 
    sem_post(&semid); 
    return 0; 
} 
+0

Qual è l'errore che hai trovato? – Jay

+0

per favore modifica la tua domanda per contenere l'errore –

+0

io non ho Linux a casa ...... questo è il programma che ho provato ad implementare al college ...... non ho knw gli errori esatti ... è stato relativo a semid .... – chinu

risposta

19

I suoi fondamenti sono sbagliate, il programma non funziona, in modo da passare attraverso le nozioni di base e riscrivere il programma.

Alcune delle correzioni è necessario fare sono:

1) È necessario fare una variabile di tipo semaforo

sem_t semvar; 

2) Le funzioni sem_wait(), sem_post() richiedono la variabile del semaforo, ma si sta passando il ID semaforo, che non ha senso.

sem_wait(&semvar); 
    //your critical section code 
sem_post(&semvar); 

3) si sta passando il semaforo per sem_wait() e sem_post() senza inizializzarla. È necessario inizializzarlo su 1 (nel tuo caso) prima di utilizzarlo, altrimenti si verificherà un deadlock.

ret = semctl(semid, 1, SETVAL, sem); 
if (ret == 1) 
    perror("Semaphore failed to initialize"); 

di studio il semaforo API? S da pagina man e passare attraverso questo example.

+0

ho un dubbio ..... se sto creando una variabile semaforo usando sem_t allora come possiamo ottenere il semidio di quella variabile ??? c'è qualche necessità di usare semid nel mio programma ???? anche dopo aver letto la pagina man, im confuso – chinu

+0

si ottiene semid usando la funzione semgets(), c'è tutto il bisogno di semid, ad esempio nel codice precedente, si può usare semid in semctl() –

+1

(sem_wait, sem_post) dovrebbe non andare insieme a semctl perché non sono compatibili. Ho appena scritto una risposta su questo –

1

Controllare questo sotto il codice di esempio per l'implementazione del semaforo (Blocca e sblocca).

#include<stdio.h> 
    #include<stdlib.h> 
    #include <sys/types.h> 
    #include <sys/ipc.h> 
    #include<string.h> 
    #include<malloc.h> 
    #include <sys/sem.h> 
    int main() 
    { 
      int key,share_id,num; 
      char *data; 
      int semid; 
      struct sembuf sb={0,-1,0}; 
      key=ftok(".",'a'); 
      if(key == -1) { 
        printf("\n\n Initialization Falied of shared memory \n\n"); 
        return 1; 
      } 
      share_id=shmget(key,1024,IPC_CREAT|0744); 
      if(share_id == -1) { 
        printf("\n\n Error captured while share memory allocation\n\n"); 
        return 1; 
      } 
      data=(char *)shmat(share_id,(void *)0,0); 
      strcpy(data,"Testing string\n"); 
      if(!fork()) { //Child Porcess 
       sb.sem_op=-1; //Lock 
       semop(share_id,(struct sembuf *)&sb,1); 

       strncat(data,"feeding form child\n",20); 

       sb.sem_op=1;//Unlock 
       semop(share_id,(struct sembuf *)&sb,1); 
       _Exit(0); 
      } else {  //Parent Process 
       sb.sem_op=-1; //Lock 
       semop(share_id,(struct sembuf *)&sb,1); 

       strncat(data,"feeding form parent\n",20); 

       sb.sem_op=1;//Unlock 
       semop(share_id,(struct sembuf *)&sb,1); 

      } 
      return 0; 
    } 
+0

@Gyan OK ... questo è nuovo .. Come passa l'id della memoria condivisa a un semaforo api che accetta un lavoro sem id qui? – Haswell

+0

infatti, credo che ci sia un errore di battitura nel codice: shm versus sem –

11

Il problema fondamentale con il tuo codice è che si mescolano due API. Purtroppo le risorse online non sono grandi a indicare questo fuori, ma ci sono due API semaforo sui sistemi UNIX-like:

  • POSIX IPC API, che è un'API standard
  • System V API, che è venuta dal vecchio mondo Unix, ma praticamente disponibile quasi tutti i sistemi Unix

Guardando il codice precedente hai usato semget() dall'API System V e ho provato a postare attraverso sem_post() che proviene dall'API POSIX. Non è possibile mescolarli.

Per decidere quale API semaforo si desidera, non si dispone di così tante grandi risorse. La cosa migliore è la "Unix Network Programming" di Stevens. La sezione che probabilmente ti interessa è in Vol # 2.

Queste due API sono sorprendentemente diverse. Entrambi supportano i semafori stile libro di testo, ma ci sono alcuni aspetti positivi e negativi nella API V Sistema vale la pena menzionare:

  • si basa sul set di semafori, quindi una volta che è stato creato un oggetto con semget(), che è un insieme di semafori piuttosto che uno singolo
  • l'API System V consente di eseguire operazioni atomiche su questi set. in modo da poter modificare o attendere più semafori in un set
  • l'API SysV consente di attendere che un semaforo raggiunga una soglia anziché essere diverso da zero.è attesa anche una soglia diversa da zero, ma la mia frase precedente implica che
  • le risorse del semaforo sono piuttosto limitate su ogni unix. è possibile controllare questi con il comando '' ipcs
  • v'è una caratteristica di annullamento dei semafori System V, in modo da poter fare in modo che la terminazione anomala del programma non lascia i tuoi semafori in uno stato indesiderato
0

Vary il tasso del consumatore e il ritmo del produttore (usando il sonno), per capire meglio il funzionamento del codice. Il codice seguente è la simulazione produttore-consumatore (oltre un limite massimo sul contenitore).

Codice per il vostro riferimento:

#include <stdio.h> 
#include <pthread.h> 
#include <semaphore.h> 

sem_t semP, semC; 
int stock_count = 0; 
const int stock_max_limit=5; 

void *producer(void *arg) { 
    int i, sum=0; 
    for (i = 0; i < 10; i++) { 

     while(stock_max_limit == stock_count){ 
      printf("stock overflow, production on wait..\n"); 
      sem_wait(&semC); 
      printf("production operation continues..\n"); 
     } 

     sleep(1); //production decided here 
     stock_count++; 
     printf("P::stock-count : %d\n",stock_count); 
     sem_post(&semP); 
     printf("P::post signal..\n"); 
    } 
} 

void *consumer(void *arg) { 
    int i, sum=0; 
    for (i = 0; i < 10; i++) { 

     while(0 == stock_count){ 
      printf("stock empty, consumer on wait..\n"); 
      sem_wait(&semP); 
      printf("consumer operation continues..\n"); 
     } 

     sleep(2); //consumer rate decided here 
     stock_count--; 
     printf("C::stock-count : %d\n", stock_count); 
     sem_post(&semC); 
     printf("C::post signal..\n"); 
     } 
} 

int main(void) { 

    pthread_t tid0,tid1; 
    sem_init(&semP, 0, 0); 
    sem_init(&semC, 0, 0); 

     pthread_create(&tid0, NULL, consumer, NULL); 
     pthread_create(&tid1, NULL, producer, NULL); 
     pthread_join(tid0, NULL); 
     pthread_join(tid1, NULL); 

    sem_destroy(&semC); 
    sem_destroy(&semP); 

    return 0; 
}