2013-03-03 4 views
5

Я получаю ошибку в следующей программе. Я хочу продемонстрировать, как два процесса могут совместно использовать переменную с помощью семафора. Может ли кто-нибудь вести меня?реализация семафора

Я не могу отлаживать ошибки ...

#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

Что это ошибка, которую вы получаете? – Jay

+0

, пожалуйста, отредактируйте ваш вопрос, чтобы он содержал ошибку –

+0

i dont hav linux у себя дома ...... это программа, которую я пытался внедрить в колледже ...... я не знаю, какие именно ошибки ... это было связанные с semid .... – chinu

ответ

19

Ваши Основы неправильны, программа не будет работать, так что идти через основы и переписать программу.

Некоторые из исправлений вы должны сделать это:

1) Вы должны сделать переменную типа семафоров

sem_t semvar; 

2) Функции sem_wait(), sem_post() требуют семафора переменной, но вы прохождения семафор id, что не имеет смысла.

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

3) Вы передаете семафор в sem_wait() и sem_post() без его инициализации. Вы должны инициализировать его до 1 (в вашем случае), прежде чем использовать его, или у вас будет тупик.

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

Исследование семафоров API от страницы человека и пройти через этот example.

+0

У меня есть сомнения ..... если im создает семафорную переменную с помощью sem_t, то как мы можем получить semid этой переменной ??? есть ли необходимость использования semid в моей программе ???? даже после прочтения man-страницы, im confused – chinu

+0

вы получаете semid с помощью функции semgets(), есть необходимость в semid, например, в приведенном выше коде, вы можете использовать semid в semctl() –

+1

(sem_wait, sem_post), чтобы не идут вместе с semctl, потому что они несовместимы. Я просто написал ответ об этом –

1

Пожалуйста, проверьте это ниже образца кода для реализации семафора (блокировка и разблокировка).

#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 ... это новое ... Как передать идентификатор общей памяти в семафор api, который принимает работу sem id здесь? – Haswell

+0

действительно, я думаю, в коде есть опечатка: shm versus sem –

11

Основная проблема с вашим кодом является то, что вы смешиваете два API. К сожалению, интернет-ресурсы не велики при указании на это, но есть два семафора API, на UNIX-подобных систем:

  • POSIX IPC API, который является стандартным API
  • System V API, которая исходит от старый практически все Unix-системы, но практически доступны почти все Unix-системы

Ознакомившись с кодом выше, вы использовали semget() из System V API и попытались отправить через sem_post(), который исходит из API POSIX. Их невозможно смешивать.

Чтобы решить, какой из семафорных API вы хотите, у вас не так много больших ресурсов. Простым лучше всего является «Сетевое программирование Unix» Стивенса. Раздел, который вы, вероятно, интересуете, находится в Vol # 2.

Эти два API удивительно отличаются. Оба поддерживают семафоры учебник стиля, но есть несколько хороших и плохих точек в System V API стоит упомянуть:

  • он строит на семафоров, так как только вы создали объект с semget(), который представляет собой набор семафоров, а не один
  • System V API позволяет выполнять атомарные операции над этими наборами. поэтому вы можете модифицировать или ждать нескольких семафоров в наборе
  • SysV API позволяет подождать, пока семафор достигнет порогового значения, а не только будет отличным от нуля.ожидая ненулевого порога, также поддерживается, но мое предыдущее предложение подразумевает, что ресурсы семафора довольно ограничены в каждом unixes.
  • . Вы можете проверить это с помощью команды «ИНКОЙ»
  • есть уничтожьте особенность семафоров System V, так что вы можете убедиться, что прекращение ненормальной программы не оставить семафоры в нежелательном состоянии
0

Вары потребительский тариф и скорость производителя (используя сон), чтобы лучше понять работу кода. Ниже приведен код моделирования потребителя-производителя (над максимальным пределом на контейнере).

Код для справки:

#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; 
} 
Смежные вопросы