Бірнеше шанышқы () Құбыры бар балалар

C ++-де бағдарлама жасауға тырысамын, ол fork() бар балалар жасайды. Ол балалардың сандарын argv-дан алуы және осы балаларды жасауы керек, әрбір бала бірін жасайды және бір-бірін құбырлармен байланыстырады.

Example ./a.exe 2

**OUTPUT**
P1 exists
P2 created
Write message: Hello
P1 sending message (“Hello”) to P2
P2 received message (“Hello”) from P1

Мен argv-дан нөмірді аламын, балалардың дұрыс санын (ойлаймын), құбырға оқуға және жазуға арналған функцияларды жасаймын, барлығы дұрыс. Бірақ мен оны бірнеше баламен жасауға қиындық туды!

  1. Бірінші мәселе, егер мен argv-да 2-ден көп болса, балаларға тапсырыс беру (кейінірек көрсетіледі)
  2. Бірақ менің үлкен мәселе, егер мен жазамын     2 сөзден тұратын хабарды тек бос орынға дейін бірінші сөзді оқуға болады. Мен scanf-ды қолданамын.

SOME OF MY CODE

//GETTING,CHECKING ARGV
//OPENING PIPE

         pid=fork();
         if (pid!=0){


                      waitpid(pid,&child_status,0);
                      printf("\n\n****Parent Process:ALL CHILD FINISHED!****");

                     }
          else if (pid==0)
          {

                 printf("\n P%d Exists \n",i); 
                     close (mypipe[READ_END]);
                      write(mypipe[WRITE_END], msg, 256);  /* write pipe*/                   
                       close (mypipe[WRITE_END]);          
                    printf("Write a message: \n");
                     scanf("%s",msg);
                       printf("\n P%d sending message: '%s' to P%d \n",i,msg,i+1); 

         do{
            childpid[i] = fork();
           if (childpid[i] > 0){   


                       /* wait for child to terminate */
                             waitpid(childpid[i],&child_status,0);  
                 }
           else if (childpid[i] == 0)
           {
               /*child process childpid = 0*/
               printf("\n P%d Created \n",i+1);
               close (mypipe[WRITE_END]);   
                 read(mypipe[READ_END], msg, 256);  /* read pipe */
                 close (mypipe[READ_END]);
                 printf("\n P%d received message: '%s' from P%d \n",i+1,msg,i);          
                 exit(0);
                 return;

            }
           else{
                   printf("Child Fork failed");
                   }
                      i++;
                   }

                   while (i

Мен басқа да осындай сұрақтарды оқып, көптеген нәрселерді көрдім, бірақ көмектесті емес !! Кез-келген көмекті бағалайтын болады! Рақмет сізге!

1
Әрине, бұл сіздің кодыңыз емес. x қалай жарияланды немесе орнатылғанын көрсетпедиң (болжам бойынша argv [1] бүтін санға түрлендіру арқылы). main() және тақырыптар сияқты кішкене нәрселерді жіберіп алдыңыз.
қосылды автор Jonathan Leffler, көзі
Сізге кейбір код көрсету қажет болуы мүмкін. Балалардан басып шығарып жатқан әдеттен тыс хабарлар туралы шағымыңыздан күдіктенемін, бірақ мен сенімді айта алмаймын. Сканерлеу мәселесі, ең алдымен, аралық буферлеуге әкелуі мүмкін, бірақ бұл жерде сіздің кодыңыздың сенімді болуы қажет еді.
қосылды автор Borealid, көзі

1 жауаптар

Сізде көрсеткен кодта бірнеше мәселе бар және түсініктемеде диагноз қойылған код жоқ.

Мәселе мынада, сіз бірінші баланың жалғыз құбырының екі жағын да жабасыз, содан кейін оны екінші рет жабыңыз (бірақ бақытсыз сіз қателікті елемейсіз). Әрине, кейінгі кез келген балалармен жұмыс істеу үшін жабық құбыр бар, және бұл оларға көмектеспейді.

Тағы бір проблема - ата-ана процесі құбырды жаппайды; бұл бағдарламада маңызды емес, себебі сіз EOF-ге оқып көрмейсіз, бірақ көптеген бағдарламаларда маңызды болар еді.

Тағы бір мәселе, стандартты енгізуден хабарды құбырға жаңартылмаған хабар жазуға тырысқанша дейін оқымайды. Баланың стандартты енгізілімін құбырдың оқылған бөлігіне жалғау керек пе екендігі анық емес. Хабар ұзаққа созылмаса да, құбырға 256 байт жазасыз.

scanf («% s», msg) бірінші бос кеңістікке (бос, жаңа жол, қойынды және т.б.) дейін оқуға арналған. Бұл тұрғыда ақпаратты оқу үшін fgets() қолданамын.

Әр бала үшін жаңа құбыр керек. Әрбір жүйелік қоңырауды қате тексеруіңіз мүмкін, бірақ бұл оңай қате туралы есеп беру функциясы болса, келесідей:

#include 
#include 
#include 
#include 
#include 

static char *arg0 = 0;

static void err_exit(const char *fmt, ...)
{
    int errnum = errno;
    va_list args;
    va_start(args, fmt);
    fprintf(stderr, "%s (%d): ", arg0, (int)getpid());
    vfprintf(stderr, fmt, args);
    va_end(args);
    if (errnum != 0)
        fprintf(stderr, "Error %d: %s\n", errnum, strerror(errnum));
    exit(1);
}

int main(int argc, char **argv)
{
    int i=1;
    int x;
    int pid, mypipe[2];
    pid_t childpid[256];
    int child_status;
    char msg[256];

    arg0 = argv[0];

    if (argc != 2 || (x = atoi(argv[1])) <= 0)
        err_exit("Usage: %s num-of-children\n", argv[0]);
    if (pipe(mypipe) < 0)
        err_exit("pipe error\n");

Хабарлама бір процестен екіншісіне ауысу үшін, сіз заттарды қалай ұйымдастырғыңыз келетіні туралы маңызды ойлар бар. Бұл жай ғана басталу ... қате туралы есеп беру функциясы сіз үшін біраз пайдаланылуы мүмкін.

1
қосылды
Сізге көмектескендеріңіз үшін үлкен рахмет! :) Мен бұрын fgets() сынап көрген болатынмын, бірақ оны дұрыс қолданбадым, енді оның ok.And мен қазір менің құбырлар дұрыс тексеріп және отладки хабарларды көрсету !! Мені босатқаныңыз үшін үлкен рахмет :)
қосылды автор DarkPain, көзі