LINUX.ORG.RU

Семафоры, не правильное отображение строки , язык си


0

2

Скопировал пример программы взаимодействия процессов с использованием семафоров и разделяемой памяти, но есть проблема, работаю в мандриве.
По коду файла server.c в консоли должно отображаться «считана строка hello world », но иногда это отображается , а иногда на консоли просто отображается «строка считана», но не пишет что именно «строка hello world считана» .Не понимаю отчего это зависит.В чём может быть проблема? В этой строке записан код отображения данной строки

printf("\nСервер:считана строка %s \n",ptr->buff);
.Вфайле shmem.h описано пару констант, тип данных, и семафоров.
Листинг файла server.c
#include <stdio.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include "shmem.h"

int main()
{
  key_t key;
  int shmid,semid;
  Message *ptr;
  key=ftok("server.c",'A'); 
  printf("Сервер:ключ = %d",(int)key);
  if(key<0)
  {
    printf("\nСервер:невозможно получить ключ");
    exit(1);
  }
  
  shmid=shmget(key,sizeof(Message),IPC_CREAT|IPC_EXCL|PERM);
  if(shmid<0)
  {
    printf("\nСервер:невозможно выделить разделяемую память\n");
    exit(1);
  }
  
  printf("\nСервер:shmid=%d",shmid);
  ptr=(Message *) shmat(shmid,0,0);
  
  if(ptr<0)
  {
    printf("\nСервер:ошибка присоединения разделяемого сегмента\n");
    exit(1);
  }
  
  semid=semget(key,2,IPC_CREAT|IPC_EXCL|PERM);
  if(semid<0)
  {
    printf("\nСервер:Невозможно создать семафор\n");
    exit(1);
  }
  printf("\nСервер:semid=%d",semid);
  
  if(semop(semid,&proc_wait[0],1)<0)
  {
    printf("\nСервер:невозможно выполнить операцию proc_wait\n");
    exit(1);
  }
  
  semop(semid,&memory_lock[0],2);
  printf("\nСервер:считана строка %s \n",ptr->buff);
  semop(semid,&memory_unlock[0],1);
  shmdt(ptr);
  
  return 0;
}  
Листинг файла client.c
 
#include <stdio.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include "shmem.h"

int main()
{ 
  key_t key;
  int shmid,semid;
  Message *ptr;
  
  key=ftok("server.c",'A');
  printf("Клиент:Key = %d",(int)key);
  if(key<0)
  {
    printf("\nКлиент:невозможно получить ключ\n");
    exit(1);
  }
  
  shmid=shmget(key,sizeof(Message),PERM);
  printf("\nКлиент:shmid=%d",shmid);
  if(shmid<0)
  {
    printf("\n Клиент:невозможно выделить разделяемую память\n");
    exit(1); 
  }
  
  ptr=(Message *)shmat(shmid,0,0);
  if(ptr<0){
    printf("\nКлиент:Ошибка присоединения\n");
    exit(1);
  }
  semid=semget(key,2,PERM);
  printf("\nКлиент:semid=%d\n",semid);
  
  if(semid<0) 
  
  
  {
    printf("\nКлиент:Невозможно получить семафор\n");
    exit(1);
  }
    
  semop(semid,&proc_start[0],1);
  semop(semid,&memory_lock[0],2);
  sprintf(ptr->buff,"Hello World!");
  semop(semid,&memory_unlock[0],1);
  semop(semid,&memory_lock[0],2);
  shmdt(ptr);
  shmctl(shmid,IPC_RMID,0);
  semctl(semid,IPC_RMID,0);
  return 0;
}  

Листинг файла shmem.h
#define MAXBUFF 80
#define PERM 0666

typedef struct mem_msg{
  int segment;
  char buff[MAXBUFF];
}Message;

static struct sembuf proc_wait[1]={1,-1,0};
static struct sembuf proc_start[1]={1,1,0};
static struct sembuf memory_lock[2]={0,0,0,0,1,0};
static struct sembuf memory_unlock[1]={0,-1,0};


       The  semaphores  in a set are not initialized by semget().  In order to
       initialize the semaphores, semctl(2) must be used to perform  a  SETVAL
       or  a  SETALL operation on the semaphore set.  (Where multiple peers do
       not know who will be the first to initialize the set,  checking  for  a
       non-zero sem_otime in the associated data structure retrieved by a sem‐
       ctl(2) IPC_STAT operation can be used to avoid races.)

И да, POSIX семафоры проще в использовании

AptGet ★★★ ()

Зачетная неделя уже закончилась, а во время подготовки к сессии доделывать лабы нельзя.

anonymous ()
Ответ на: комментарий от Raxem

Я ни каких лаб не сдаю))Я лишь пытаюсь понять почему стандартный пример из книги работает не совсем правильно

От таких примеров кстати больше толку, чем от рабочих )

Deleted ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.