fork exec işlemleri

Başlatan PMI, 28 Şubat 2014 - 16:40:50

« önceki - sonraki »

0 Üyeler ve 1 Ziyaretçi konuyu incelemekte.

PMI

Merhabalar
direk örnek kod verip başlayayım

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
void
main(void){
    int RD;
    unsigned int buf;

    printf("3+4+5=?\n");
    RD=read(0,&buf,100);
    if(RD<0){
        perror("FAIL\n");
        exit(EXIT_FAILURE);
    }   
}

ben bu kodu başka bir programın içerisinden çağırıp 3,4,5 rakamlarını bir diziye
aktarıp işlem sonucunu programa tekrar vermek istiyorum.
işlem sonucunu nasıl veririm kısmını çözebilirsek başka sorunum yok
yalnız program bir kere çalışacak defalarca değil.aklıma fork exec geldi
ama nasıl yapacağımı hala çözemedim.yardımcı olursanız sevinirim.
lanet olsun dostum sadece biraz gerginim

sem

Merhabalar, bir prosesin çıktısını diğerine aktarmak istiyorsanız pipe'dan yararlanabiliriz. İki proses arasında birincil - çocuk (parent - child) ilişkisi olan haberleşmede isimli borularuı kullanabilirsiniz.

Hemen hemen dosyaya yazıp okumaktan farkı yoktur gibi düşünebiliriz. file open; fopen() fonksiyonunda olduğu gibi pipe open işlemi için de popen() metodu kullanılabilir;

http://stackoverflow.com/questions/17107365/get-system-command-output-in-c-program

Buradaki verilen örnekte olduğu gibi.
".NET çemberinden geçen lirisist etkisi bir 'Volcano', bir yüzüm Java bir yüzüm Badalamenti Don Tano"
----------------------------------------------------------------------------------------------------------------------
"Her yer ölüm yine, burası dünya
Derken ölüm bile bu nasıl dünya?
Benden ölüm dile, batıyor gün yine
Burası dünya?

PMI

ilk kodda ekrana datalar basıldıktan sonra readle bizden veri bekliyor olacak
biz ekrana basılan dataları yeni programımızda içeri alabiliriz ama readle beklenen
işleme nasıl cevap döndeririz bu kısmını merak ediyorum verdiğiniz linkten yola çıkarak
bunu başarmak mümkün olabilir ama daha önce hiç böyle bi şey yapmadığım için
ne yapacağımdan emin olamadım şu an,mesela stdouta direk değer göndersek bu
içerde çalışan read için yorumlanabilir bir inputmudur ve ya çalıştırılabilir program için
bir file descriptor oluştursak bu file descriptora veri yazmaya çalıştığımızda istediğim şeyi
başarmış mı olurum biraz daha  yardımcı olursanız sevinirim bu gidişle yapamayacam bişey
lanet olsun dostum sadece biraz gerginim

PMI

Sorunum hala devam ediyor çift yönlü haberlerşmeyi başaramadım
eğer kimsenin bir fikri yoksa konu kilitlenebilir.
lanet olsun dostum sadece biraz gerginim

WhiteScars

Biraz sağa sola bakıp, bişiler yaptım. Aşağıdaki kod sanırsam istediğin işi yapıyor.

2 tane program,

Birincisi: Diğer programı çalıştırıp, işlemi hesaplatıp cevabını alacak olan program.

Derlemek için
gcc program.c -o program.o
program.c

#include <stdio.h>
#include <stdlib.h>


int main( int argc, char *argv[] )
{

  FILE *fp;
  int status;
  char path[1035];

  /* Open the command for reading. */
  fp = popen("/home/i7-haswell/test/diger.o 2 3 4", "r"); // Burada diger programın tam bulunduğu dizini yazman lazım.
  if (fp == NULL) {
    printf("Failed to run command\n" );
    exit;
  }

  /* Read the output a line at a time - output it. */
  while (fgets(path, sizeof(path)-1, fp) != NULL) {
    printf("%s", path);
  }

  /* close */
  pclose(fp);

  return 0;
}


Diğeri: Bu da işlem için gerekli parametreleri yukardaki programdan alıp, işlemi yapıp, cevabını ekrana koyacak olan program. Cevabı ekrana koyduğunda birinci program bu cevabı okuyacak

derlemek için

gcc diger.c -o diger.o

diger.c

#include <stdio.h>
#include <stdlib.h>


int main( int argc, char *argv[] ) // argc - kaç tane parametre gönderildiği, argv, parametreler.
{
    int i;

    int toplam = 0;
    int param = 0;
    // Dongu 1'den basliyor. ilk parametre programin adi
    for ( i = 1; i < argc; ++i)
    {
param = atoi(argv[i]); // parametreler character tipinde pointer oldukları için bunları önce integer'a çevirmen lazım.
        toplam = toplam + param;
        //printf("argv[%d]: %s\n", i, argv[i]);
    }
    printf ("%d\n", toplam);
    return 0;
}


Basitce, ilk program 2. programı parametreler vererek çalıştırıyor. Yukardaki kodda 2,3,4 parametre olarak verilmiş. Diğer program ise bu parametreleri alıp okuyup, hepsini topluyor. Sen nasıl bir işlem yapmak istiyorsan ona göre değiştirebilirsin.

Çalıştığında aşağıdaki gibi bir çıktı vermesi lazım. Zira bende böyle veriyor  ;D


whitescars@i7-haswell:~/test$ ./program.o
9
İnsanoğluna bırakabileceğiniz en güzel miras tecrübelerinizdir.

PMI

İlginiz için teşekkürler ama istediğim şey tam olarak bu değildi.
bu işi çözse çözse borular çözer ben şöyle bir kod yazdım aslında
gayet başarılı çalışıyorda iki işi yapamıyor biraz değiştirince  sadece okuma
yapıp buf değişkenini dolduruyor ama bişey gönderemiyor tekrar değiştirince yazma yapabiliyor
ama buf değişkenini dolduramıyor tam da anlatamıyorum programı çalıştırıp trace ederseniz
ne demek istediğimi anlarsınız ben burada isimsiz boruları kullandım


#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <pthread.h>
/*
static char BOB[10];
*/

void ERR_SYS(const char *msg);
/*
void write_func(int FD);
void *thread_func(void *);
void read_func(int FD);
*/
int
main(void){

    int FD;
    char buf[15];
    char buf2[15];
    int fdp[2];
    int rdp[2];
    pid_t childpid;

/*
    pid_t ppid;
    pthread_t tid;
    FILE *fpen;
   
    memset(BOB,'\0',10);
   */
    memset(buf,'\0',14);


    if(pipe(fdp) < 0 || pipe(rdp) < 0)
ERR_SYS("fail_pipe");

    if((childpid = fork()) < 0)
ERR_SYS("fail_fork");

    if(childpid==0)
    {
close(fdp[1]);
close(rdp[0]);
dup2(rdp[1],1);
dup2(fdp[0],0);
    execle("./lol",NULL,NULL,NULL);
    }else{

close(rdp[1]);
close(fdp[0]);
dup2(rdp[0],0);
dup2(fdp[1],1);

//fread(buf,5,1,stdin);
read(rdp[0],buf,4);
close(rdp[0]);

int x=5;
        while(x<10)
{
    ++x;
    printf("%d-buf::%s\n",x,buf);
}
write(fdp[1],"off",3);
wait(NULL);
   }
   return 0;
}

void
ERR_SYS(const char *msg)
{
    perror(msg);
        exit(EXIT_FAILURE);
}




/* lol.c programı bu*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
void
main(void){
    int RD;
    unsigned int buf;

    printf("3+4+5=?\n");
    RD=read(0,&buf,100);
    if(RD<0){
        perror("FAIL\n");
        exit(EXIT_FAILURE);
    }   
}

Trace çıktısı

[pid 3832] __libc_start_main(0x804867c, 1, 0xbfae5c74, 0x8048890, 0x8048900 <unfinished ...>
[pid 3832] memset(0xbfae5bbd, '\000', 14)                                                                               = 0xbfae5bbd
[pid 3832] pipe(0xbfae5bac)                                                                                             = 0
[pid 3832] pipe(0xbfae5bb4)                                                                                             = 0
[pid 3832] fork()                                                                                                       = 3833
[pid 3832] close(6)                                                                                                     = 0
[pid 3832] close(3)                                                                                                     = 0
[pid 3832] dup2(5, 0)                                                                                                   = 0
[pid 3832] dup2(4, 1)                                                                                                   = 1
[pid 3832] read(5,  <unfinished ...>
[pid 3833] <... fork resumed> )                                                                                         = 0
[pid 3833] close(4)                                                                                                     = 0
[pid 3833] close(5)                                                                                                     = 0
[pid 3833] dup2(6, 1)                                                                                                   = 1
[pid 3833] dup2(3, 0)                                                                                                   = 0
[pid 3833] execle(0x8048934, 0, 0, 0, 0xb76f83e4 <unfinished ...>
[pid 3833] --- Called exec() ---
[pid 3833] __libc_start_main(0x804852c, 0, 0xbfd619a4, 0x80485c0, 0x8048630 <unfinished ...>
[pid 3833] puts("3+4+5=?")                                                                                              = 8
[pid 3833] read(0, BURADA TIKANDIM
lanet olsun dostum sadece biraz gerginim

blackwidow

Hocam bunun yerine pid_t pid; ile yapsaydınız da bence iyi çalıştırabilirdiniz.

Pid -1 ise fork error

pid = 0 ise çocuk oluyor , buraya yaptırıcaksınız işlemi .

diğer türlü de baba oluyor

pid = 0 ' ın içinde exit yapıp en dıştaki else ' de de çocukların ölmesini bekliyoruz .

Kodunuzu inceliyorum extra pipe için iyi örnek