LINUX.ORG.RU

Использовать семафоры для взаимного исключения

 


0

2

Добрый день, подскажите что в этой программе не так?(нужно использовать семафоры для взаимного исключения)


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

const int INC_DEC = 500000;

int main() {

int shmid = 777,semid;
int *array;
char pathName[] = "program6_2_7.c";
int var = 0;
int new=1;
key_t key;
struct sembuf mybuf;
if ((key = ftok(pathName,0)) < 0)
 {
  printf("can't generate key\n");
  return -1;
 }

if ((shmid = shmget(key, 1*sizeof(int), 0666 | IPC_CREAT | IPC_EXCL))< 0)
 {
  if (errno != EEXIST)
  {
  printf("Cant create shared memory1\n");
  exit(-1);
  }
else
   {
    if ((shmid = shmget(key, 1*sizeof(int),0))< 0)
    {
    printf("Cant create shared memory2\n");
    exit(-1);
    }
   }
  if ((array = (int*)shmat(shmid, NULL,0)) == (int*)(-1))
  {
  printf("Cant attach shared memory\n");
  exit(-1);
  }
 }

semid = semget(key,1,0666 | IPC_CREAT);
mybuf.sem_op = 0;
mybuf.sem_flg = 0;
mybuf.sem_num = 0;
array[0] = var;
int f = fork();

if (f > 0)
  {
  semop(semid, &mybuf,1);
  for (int i = 0; i < INC_DEC; ++i)
    {
    array[0]-=1;
    mybuf.sem_op=-1;
    semop(semid, &mybuf,1);
    }
  printf("Parent dec var = %d", array[0]);
  }
else
  {
  semop(semid, &mybuf,1);
  for (int i = 0; i < INC_DEC; ++i)
   {
   array[0]+=1;
   mybuf.sem_op=1;
   semop(semid, &mybuf,1);
   }
  printf("Child inc var = %d",array[0]);
  }
return 0;
}



Последнее исправление: vladzakharov97 (всего исправлений: 2)

Ответ на: комментарий от tailgunner

Ответ

У одного из процессов(родитель, ребёнок) должен быть выведен в printf «0», т.к. семафоры взаимно исключают эти 2 процесса

vladzakharov97
() автор топика
Ответ на: Ответ от vladzakharov97

Отступов нет.

У одного из процессов [skip]

Процессы в данном случае ни при чём. Человек намекнул, что код, оформленный таким образом, читать, мягко говоря, сложно. И мало кто будет этим заниматься, если вообще хоть кто-то найдётся. Оформи нормально, как-то так:

int main() {

 int shmid = 777,semid;
 int *array;
 char pathName[] = "program6_2_7.c";
 int var = 0;
 int new=1;
 key_t key;
 struct sembuf mybuf;

 if ((key = ftok(pathName,0)) < 0)
 {
   printf("can't generate key\n");
   return -1;
 }

 printf("key = %d\n", key);

 if ((shmid = shmget(key, 1*sizeof(int), 0666 | IPC_CREAT | IPC_EXCL))< 0)
 {
  if (errno != EEXIST)
  {
   printf("Cant create shared memory1\n");
   exit(-1);
  }
  else
  {
   if ((shmid = shmget(key, 1*sizeof(int),0))< 0)
   {
    printf("Cant create shared memory2\n");
    exit(-1);
   }
 }
 // etc...

и поправь верхний пост. А заодно можно добавить вывод программы с указанием, что не так.

aureliano15 ★★
()
Ответ на: Ответ от vladzakharov97

Как там может быть выведен 0, если printf закомментированы, а в array[0] ещё до printf в одном случае становится <0, а в другом >0.

Вы напишите как у вас семафоры должны «взаимно исключают эти 2 процесса», чтобы один из процессов ждал, пока другой не выполнит весь for, или чтобы они в for поочерёдно (как получится) крутили счётчик туда-обратно?

Семафон нужно сначала установить в заданное число (ещё до fork) с помощью semctl(), а потом программа должна делать с семафором (-1), это LOCK если semop() успешно, а после освобождать операцией (+1). Это если нужно блокироваться при ожидании. Или делать две опрации на одном семафоре в одном semop() — 0 ждать и +1 для LOCK, а потом -1 для UNLOCK.

mky ★★★★★
()
Последнее исправление: mky (всего исправлений: 1)
Ответ на: комментарий от mky

Если вам нужно обязательно поочерёдное выполнение родитель-потомок-родитель-потомок..., то делайте два семафора. Один процесс разблокирует один семафор и засыпает на другом, а другой процесс наоборот.

mky ★★★★★
()
Ответ на: комментарий от mky

Ответ:

Спасибо за помощь, я пока не совсем понимаю как это реализовать, но буду разбираться.

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