Автор Тема: [решен] fork() проблеми  (Прочетена 2775 пъти)

Arvigeus

  • Напреднали
  • *****
  • Публикации: 123
  • Distribution: Arch Linux
  • Window Manager: Whatever
    • Профил
[решен] fork() проблеми
« -: Apr 18, 2011, 11:05 »
Здравейте! Опитвам се да съставя програма, която създава два процеса: единият чете, другият извежда. Проблемът е, че  увисва още при започване. Ето го кодът, ако някой може да ми каже какъв е проблема:
Код
GeSHi (C):
  1. #include <unistd.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. struct point {
  6.  int ID;
  7.  char* text;
  8.  int lock;
  9.  int readed;
  10. }*p;
  11.  
  12. extern getmem(int memory);
  13. extern testandset(int *lock);
  14.  
  15. char *messages[] = {
  16.  "Segmantation Fault",
  17.  "Unhandled Exception",
  18.  "Stack Overflow",
  19.  "Core Dump",
  20.  "General Protection Fault",
  21.  "Page Fault",
  22.  "Storage Violation",
  23.  "Bounds Check Fault",
  24.  "Null Pointer Exception",
  25.  "Divide Fault",
  26.  "NMI Interrupt",
  27.  "Overflow Trap",
  28.  "Invalid Opcode Fault",
  29.  "Runtime Error",
  30.  "Unspecified Fatal Error",
  31.  "Nuff said",
  32.  "Invalid Task State Segment Fault",
  33.  "Not Present Fault",
  34.  "Access Violation",
  35.  "Invalid Option",
  36.  "" /* The last message will never got read, so put it empty string is used */
  37. };
  38.  
  39. int main(void) {
  40.  int pid, id=-1;
  41.  
  42.  p = (struct point *)getmem(666);
  43.  p->readed = 1;
  44.  p->lock = 0;
  45.  p->ID = 0;
  46.  
  47.  switch(fork()) {
  48.    case -1: /* Error */
  49.      printf("Fork error! Exiting...\n");
  50.      return 1;
  51.      break;
  52.    case 0: /* Child -  Reading Messages */
  53.      while(messages[id+1]!=NULL) {
  54.      while (testandset(&(p->lock))) {}
  55.      if(p->ID!=id) {
  56.        printf("%s\n", p->text);
  57.        if(id==-1) sleep(3);
  58.        else sleep(1);
  59.        id = p->ID;
  60.      }
  61.      p->readed = 1;
  62.      p->lock = 0;
  63.      }
  64.      printf("\n\tEnd of child process\n");
  65.      break;
  66.  default: /* Parrent - Generate Messages */
  67.    while(messages[p->ID]!=NULL) {
  68.      while(p->readed==0) {}
  69.      while (testandset(&(p->lock))) {}
  70.      p->text = messages[p->ID];
  71.      p->ID++;
  72.      p->readed = 0;
  73.      p->lock = 0;
  74.    }
  75.    wait();
  76.    printf("\n End of parent process\n");
  77.  }
  78.  return 0;
  79. }
???
« Последна редакция: Apr 20, 2011, 18:59 от Arvigeus »
Активен

bop_bop_mara

  • Напреднали
  • *****
  • Публикации: 2433
  • Distribution: Debian Testing
  • Window Manager: LXDE
  • Cute and cuddly
    • Профил
Re: fork() проблеми
« Отговор #1 -: Apr 18, 2011, 11:15 »
Аз ли греша, или това "бащата пише, детето чете" става през структурата? Ако е така, прочети отново какво се случва при fork(), а след това се заеми и с четене за shared memory (или IPC като цяло) :).

Също така, за по-добър стил, проверявай дали резултата, който върне fork() не е -1 (т.е. грешка), недей да разделяш случаите просто на 0 и не-0 :)
Активен

mpakmop

  • Участници
  • ***
  • Публикации: 4
    • Профил
Re: fork() проблеми
« Отговор #2 -: Apr 18, 2011, 11:37 »
А защо test_and_set() винаги връща 0? Така програмата никога няма да влезе в while циклите по-долу.
Активен

bop_bop_mara

  • Напреднали
  • *****
  • Публикации: 2433
  • Distribution: Debian Testing
  • Window Manager: LXDE
  • Cute and cuddly
    • Профил
Re: fork() проблеми
« Отговор #3 -: Apr 18, 2011, 11:48 »
А защо test_and_set() винаги връща 0? Така програмата никога няма да влезе в while циклите по-долу.
Не е това фаталното в случая, а и употребата не е за условие за влизане в цикъл, а while(test_and_set()) {} - т.е. за ключалките.

Edit: Но, да, и механизмът за заключване "куца".
« Последна редакция: Apr 18, 2011, 11:59 от bop_bop_mara »
Активен

bvbfan

  • Напреднали
  • *****
  • Публикации: 1056
  • Distribution: KaOS
  • Window Manager: Plasma 5
    • Профил
Re: fork() проблеми
« Отговор #4 -: Apr 18, 2011, 12:59 »
Цитат на: Arvigeus
      while(p->ID<20) {
        while(test_and_set()) {}
        if(p->ID!=id) {
          printf( "Message %d:\t%s\n", p->ID, p->text);
          id = p->ID;
        }
        p->readed = 1;
        p->lock = 1;
      }

Безкраен цикъл, може би p->ID++ ?
Освен това, char text[50]; strcpy(p->text, messages[0]);  ??? много тъпо, когато ползваш статични текстове, както в случая, не използвай буфери, камо ли strcpy, поне sprintf( p->text, "%.49s", message[0]); може просто
struct point {
  int ID;
  const char *text;
  int lock;
  int readed;
}*p;
 
static const char *messages[] = { ... }; p->text = message[0];
Активен

Arvigeus

  • Напреднали
  • *****
  • Публикации: 123
  • Distribution: Arch Linux
  • Window Manager: Whatever
    • Профил
Re: fork() проблеми
« Отговор #5 -: Apr 18, 2011, 22:38 »
Благодаря за съветите! Просто от ужасно много време не съм ползвал C и всеки път ми е малко странно.
Коригирах си горният пост. Това с test_and_set() явно се е объркало при копирането, защото иначе си беше "правилния" вариант.
Засега програмата  пак не работи (стига си до същата точка)...
Активен

bop_bop_mara

  • Напреднали
  • *****
  • Публикации: 2433
  • Distribution: Debian Testing
  • Window Manager: LXDE
  • Cute and cuddly
    • Профил
Re: fork() проблеми
« Отговор #6 -: Apr 18, 2011, 23:36 »
Благодаря за съветите! Просто от ужасно много време не съм ползвал C и всеки път ми е малко странно.
Коригирах си горният пост. Това с test_and_set() явно се е объркало при копирането, защото иначе си беше "правилния" вариант.
Засега програмата  пак не работи (стига си до същата точка)...
OK, ще ти го кажа направо, когато процес създаде процес-дете, адресното пространство се копира, а не се споделя (няма как да е иначе, замисли се какъв хаос би настъпил). Няма как да ти работи замисъла на програмата с този код. Прочети какво прави fork(), прочети какво е IPC и си избери някой механизъм (например shared memory).
Активен

sdr

  • Напреднали
  • *****
  • Публикации: 655
    • Профил
Re: fork() проблеми
« Отговор #7 -: Apr 19, 2011, 14:01 »
pthread.h му е майката за това което се опитваш да направиш. Нишките за разлика от процесите поделят общо адресно пространство. Ако се каниш да си отделяш IO-то от "бизнес логиката" по-добре ползвай разните му select/poll диревати :)
Активен

Arvigeus

  • Напреднали
  • *****
  • Публикации: 123
  • Distribution: Arch Linux
  • Window Manager: Whatever
    • Профил
Re: [решен] fork() проблеми
« Отговор #8 -: Apr 20, 2011, 19:02 »
Проблемът е решен. За съжеление поради ограниченото ми време използвах библиотека, предоставена ми от училище, която май не спазва много-много стандартите. Редактирал съм кода, във "работеща" версия, само дето няма да може да ви се компилира без тази библиотека. Ако някой все пак прояви някакъв интерес, може да ми пише. Но задачата наистина е тривиална, така че...
Активен

Подобни теми
Заглавие Започната от Отговора Прегледи Последна публикация
exec() и fork()
Коментар
Airfan 3 2824 Последна публикация Jun 22, 2005, 11:43
от Йордан
Въпрос cron - fork-ва ли се демона или ?
Настройка на програми
Explisit 4 2412 Последна публикация Jul 21, 2010, 11:53
от sdr
fork на gpl/agpl проект
Идеи и мнения
gotha 0 1332 Последна публикация Jul 21, 2010, 10:56
от gotha