pipeline tam olarak nedir

Başlatan Neof07, 05 Nisan 2017 - 00:17:23

« önceki - sonraki »

0 Üyeler ve 1 Ziyaretçi konuyu incelemekte.

Neof07

C üzerinde pipeline ile ilgili örnek gösterebilir misiniz ? Kaynak var ancak türkçe olmadığından pek anlayamadım. Açıklayıcı olucak bir şekilde örnek paylaşılırsa sevinirim.

guestwho

#1
Basit bir şekilde anlatmaya çalışayım. Linux çekirdeği üzerinden işlemler arasında "pipe()" fonksiyonu (sistem çağrısı) ile bir iletişim kanalı kurulabiliyor. İletişim 2 şekilde gerçekleşebiliyor:

1-) Ana işlem -> Çekirdek -> Yan işlem:  Ana işlemden gönderilen mesajı çekirdek yan işleme iletiyor.

2-) Ana işlem <- Çekirdek <- Yan işlem: Yan işlemden gönderilen mesajı çekirdek ana işleme iletiyor.

Şöyle bir şemamız var:



Yani çekirdek bir tarafın çıktısı ile diğer tarafın girdisini birbirine bağlıyor. Bu kanal üzerinden mesaj göndermek için "write()", okumak içinse "read()" fonksiyonları (sistem çağrıları) kullanılıyor. Örnek kod:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>

int main() {
// kanalın giriş ve çıkış yönlerini temsilen
int     fd[2], nbytes;

// mesajın yönünü ifade etmek için çekirdek tarafından döndürülen değer
pid_t   childpid;

// gönderilecek olan mesaj
char    msg[] = "ping\n";

// maksimum mesaj boyutu
char    readbuffer[40];

// iletişim kanalını oluşturan sistem çağrısı
pipe(fd);

// hata kontrolü
if((childpid = fork()) == -1) {
perror("fork işlemi başarısız!");
exit(1);
}

if(childpid == 0) {
// kanalın giriş tarafını kapat
close(fd[0]);

// çıkış tarafına mesajı yazdır
write(fd[1], msg, (strlen(msg)+1));
printf("Kanaldan gönderilen mesaj: %s", msg);
exit(0);
} else {
// kanalın çıkış tarafını kapat
close(fd[1]);

// kanaldan gelen mesajı oku
nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
printf("Kanaldan gelen mesaj: %s", readbuffer);
}

return(0);
}


Yukarıdaki anlatımda birbiriyle ilintili 2 işlem arasında iletişim kanalı kurmuş olduk. Bu iletişim kanalının bir de birbirinden bağımsız işlemler arasında iletişim kurmak için kullanılan "named pipe" diye bir türevi var. Bu türden iletişim kanalı oluşturmak içinse "mkfifo" sistem çağrısı kullanılıyor. Şimdi bu türden iletişim kanalı üzerinden okuma ve yazma yapan 2 ayrı uygulama yazalım ve bunları birbiriyle haberleştirelim. Kanal üzerinden mesaj gönderen uygulamamız şu şekilde:

#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

int main()
{
int fd;
char * myfifo = "/tmp/myfifo";
char line[256];

// FIFO ("named pipe") oluştur
mkfifo(myfifo, 0666);

        // yazmak için kaynağa erişim ver
fd = open(myfifo, O_WRONLY);

        // giriş yapıldığı sürece kanala mesaj olarak gönder
while(fgets(line, sizeof(line), stdin) != NULL) {
write(fd, line, sizeof(line));
}

        // kaynağı kapat
close(fd);

// FIFO 'u kaldır
unlink(myfifo);

return 0;
}


Bunu "writer.c" diye kaydedip, şu şekilde derliyoruz:

gcc writer.c -o writer

Şimdi de kanal üzerinden gelen mesajları sürekli okuyan ayrı bir uygulama yazalım:

#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>

#define MAX_BUF 1024

int main()
{
int fd;
char * myfifo = "/tmp/myfifo";
char buf[MAX_BUF];

/* okumak için kaynağa erişim ver
fd = open(myfifo, O_RDONLY);

while(read(fd, buf, MAX_BUF)) {
printf("Mesaj: %s", buf);
}

close(fd);
return 0;
}


Bunu da "reader.c" diye kaydedip, derleyelim:

gcc reader.c -o reader

Şimdi önce "writer" sonra da "reader" uçbirimde çalıştırıldığında, "writer" tarafından girilen mesajlar, kanalın diğer ucundaki "reader" tarafından sürekli okunup ekrana basılacaktır. "Ctrl+C" ile uygulamalardan çıkış yapabilirsin.
You want weapons? We're in a library. Books are the best weapon in the world. This room's the greatest arsenal we could have. Arm yourself!