Премини към съдържанието
Форумът в приложение

По-лесно сърфиране. Научи повече.

Kaldata.com - Форуми

Приложение на форума на цял екран с push известия, значки и други.

За да инсталирате това приложение на iOS и iPadOS
  1. Докоснете Иконата за споделяне в Safari
  2. Превъртете менюто и докоснете Добавяне към началния екран.
  3. Докоснете Добавяне в горния десен ъгъл.
За да инсталирате това приложение на Android
  1. Докоснете менюто с 3 точки (⋮) в горния десен ъгъл на браузъра.
  2. Докоснете Добавяне към началния екран или Инсталиране на приложение.
  3. Потвърдете, като докоснете Инсталиране.

Добре дошли!

Добре дошли в нашите форуми, пълни с полезна информация. Имате проблем с компютъра или телефона си? Публикувайте нова тема и ще намерите решение на всичките си проблеми. Общувайте свободно и открийте безброй нови приятели.

Моля, регистрирайте се за да публикувате тема и да получите пълен достъп до всички функции.

 

Създаване C програми за работа на паралелни процеси(с използване на семафори).

Featured Replies

Условие:

Да се създадат три независими процеса,комуникиращи през обща памет с размер един символ.Първият процес чете от потребителя символен низ и го предава символ по символ през общата памет на втория процес,който го предава през общата памет на третия процес,преобразуван с главни букви.Третият процес визуализира полученият символен низ на екрана.

Да се създадат три независими процеса,комуникиращи през обща памет с размер един символ.Първият процес чете от потребителя символен низ и го предава символ по символ през общата памет на втория процес,който го предава през общата памет на третия процес,преобразуван с главни букви.Третият процес визуализира полученият символен низ на екрана.

 

Трябва ми малко помощ от някой с повече познания за работа със семафори(ако е възможен друг начин за създаване на работеща програма пак е приемлив вариант).Писани са на Убунту 10.10.Направил съм 1 процес за инициализиране на 3 семафора(по 1 за всеки процес) и 3 процеса,като всеки един изпълнява конкретната си задача.Проблема е,че се получава някаква блокировска и след стартиране на скрипта успешно се създават 3те семафова,но след това нито 1 процес тръгва.Ако някой може да погледне кода и да каже,дали проблема е изцяло в алгоритъма или е нещо друго.

 

/////////////////////         init.c

#include "shared.c"
#include <stdio.h>

main(){
    sem_t s1 = sem_init(3001);
    sem_t s2 = sem_init(3002);
    sem_t s3 = sem_init(3003);
    sem_set (s1, 1);
    sem_set (s2, 0);
    sem_set (s3, 0);
    
}
 

Процес №1

#include "shared.c"
#include <stdio.h>
#include <string.h>

main(){
    char *buffer1;
    buffer1 = (char *)getmem(25);

    int x;
    x = (int )getmem(300);

    char entry[30] = "sentry";
    sem_t s1 = sem_init(3001);
    sem_t s2 = sem_init(3002);

    int i;
/*
printf("Enter a string");
scanf("%s", &entry[30]);
*/
x = strlen(entry);
printf("%d\n\n\n\n", s1);

for (i=0; i<x; i++){
    PS(s1);
    printf("Entered process 1");    
    *buffer1 = entry;
    VS(s2);    
    }
sem_remove(s1);
}
//////////////////////////////////////////////////////////////////////////////////////

 

 

Процес №2

#include "shared.c"
#include <stdio.h>
#include <string.h>

main(){
    int enable = 0;
    enable = (int )getmem(30);
    char *buffer1;
    char *buffer2;
    buffer2 = (char *)getmem(33);
    int x;
    x = (int)getmem(300);
    buffer1 = (char *)getmem(25);
    sem_t s2 = sem_init(3002);
    sem_t s3 = sem_init(3003);
    int i;


for (i=0; i<x; i++){
    PS(s2);
    printf("Entered process 2");    
    *buffer2 = toupper(*buffer1);
    enable++;
    VS(s3);    
    }
}

///////////////////////////////////////////////////////////////////////

 

Процес №3

 

#include "shared.c"
#include <stdio.h>
#include <string.h>

main(){
    int x;
    x = (int)getmem(300);
    int enable;
    enable = (int )getmem(30);
    char *buffer2;
    buffer2 = (char *)getmem(33);
    sem_t s1 = sem_init(3001);
    sem_t s3 = sem_init(3003);
    char outPut[30];
    int i;

for (i=0; i<x; i++){
    PS(s3);
    printf("Entered process 3");    
    outPut = *buffer2;

    if ( enable == x){
    printf("%s \n", outPut);
    }
    VS(s1);
    }
}

//////////////////////////Всеки процес е отделен *.c файл.Стартирам ги с един баш скрипт.

 

  • Автор

Нищо не извеждаше и реших да напиша:

 char entry[30] = "sentry";.

Просто има някакъв стринг за извеждане по подразбиране.

Нищо не извеждаше и реших да напиша:

 char entry[30] = "sentry";.

Просто има някакъв стринг за извеждане по подразбиране.

Какво има в тоя shared.c, който включваш? Каква е тази имплементация на семафори, която ползваш? Не е POSIXката, тя има друг интерефейс за sem_init...
  • Автор

Да забравих да спомена,че shared.c е някаква библиотека правена от някой от катедрата.

 

//
// shared.c
// Routines:
//    - getmem (common memory)
//    - TestAndSet
//    - Semaphore operations P and V
//      semaphores are implemented with pointers

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

#define SEMKEY 88
#define SHMSIZE 64


//
// ========================= Shared memory =====================
//

void * getmem (int i){
int shmid;

  shmid = shmget(70+i, SHMSIZE, IPC_CREAT|0666);
  return shmat(shmid,0,0);
}

//
// ======================== Semaphore operations ==========================
//


int shmid, semid;
int i, *pint, status, id;

short out[1],
      oldval;

struct sem_str {
  int semid;
  short init[1];
  struct sembuf p, v;
};

typedef struct sem_str *sem_t;  

sem_t sem_init(int i)
{ sem_t s;
 
  s = (sem_t) malloc(sizeof(struct sem_str));
  s->semid = semget(SEMKEY+i,1,IPC_CREAT|0777);

  s->p.sem_num = 0;
  s->p.sem_op = -1;
  s->p.sem_flg = 0;

  s->v.sem_num = 0;
  s->v.sem_op = 1;
  s->v.sem_flg = 0;

  return s;
}

void sem_set(sem_t s, int value)
{  
  s->init[0]=value;
  semctl(s->semid,1,SETALL,s->init);
}

void PS(sem_t s)
{
  int oldval;
 
  oldval = semop(s->semid,&(s->p),1);
}

void VS(sem_t s)
{
  int oldval;
 
  oldval = semop(s->semid,&(s->v),1);
}

void sem_remove(sem_t s)
{
  semctl(s->semid,1,IPC_RMID,0);
  free(s);
}

//
// ===================== TestAndSet ============================
//

//static __inline__
int testandset(volatile int *spinlock)
{
  int ret;
 
    __asm__ __volatile__(
           "xchgl %0, %1"
           : "=r"(ret), "=m"(*spinlock)
           : "0"(1), "m"(*spinlock)
           : "memory");
                                
    return ret;
}
 

Съдържа функции за дефиниране на семафори,декрементиране и инкрементиране и премахване на семафов.

Проблемът ти изобщо не е в семафорите, ами в това че не работиш правилно със споделената памет - по точно с указателите.
Функцията getmem връща указател към споделена памет, не число. След което присвояваш указателите на променливите x и enable като число. Така всеки процес си ги ползва като негови си, вместо общата памет, както очакваш.
Между другото тези променливи (очевидно) са споделени и също трябва да бъдат защитени от едновременен достъп с техен си семафор. В реална система, особено като линукс или уиндоус (тоест многозадачна, многопроцесорна и не realtime), нищо не ти гарантира че процес три няма да започне да се изпълнява преди процес едно, независимо кой си пуснал първо, което от своя страна ще доведе до грешно изпълнение. Винаги защитавай споделените си ресурси.
Но една забележка преди това. Грешката с указателите е елементарна. Изобщо не се очаква да правиш такива грешки, когато си стигнал до семафори. Вземи и си прочети нещата за указателите пак. Многозадачното програмиране и без това има много подводни камъни, ще си причиниш много проблеми, ако се навираш там, а не можеш да работиш добре с по-простите неща.

Редактирано от flare (преглед на промените)

Архивирана тема

Темата е твърде стара и е архивирана. Не можете да добавяте нови отговори в нея, но винаги можете да публикувате нова тема, в която да продължи дискусията. Регистрирайте се или влезте във вашия профил за да публикувате нова тема.

Разглеждащи това в момента 0

  • Няма регистрирани потребители разглеждащи тази страница.

Дарение

  • Подкрепи съществуването на форума - направи дарение
    25%
    Дарени 252.69 EUR от нужните 1,000.00 EUR

Бюлетин

Получавайте известие, когато има важна промяна или новина свързана с форума.

Профил

Навигация

Търсене

Търсене

Конфигуриране на push известия в браузъра

Chrome (Android)
  1. Докоснете иконата на катинар до адресната лента.
  2. Докоснете Разрешения → Известия.
  3. Променете предпочитанията си.
Chrome (Desktop)
  1. Кликнете върху иконата на катинар в адресната лента.
  2. Изберете Настройки на сайта.
  3. Намерете Известия и коригирайте предпочитанията си.