Gọi hệ thống ống trong C

Pipe System Call C



đường ống() là một chức năng của hệ thống Linux. Các đường ống() chức năng hệ thống được sử dụng để mở các bộ mô tả tệp, được sử dụng để giao tiếp giữa các quy trình Linux khác nhau. Trong ngắn hạn, đường ống() chức năng được sử dụng để giao tiếp giữa các quá trình trong Linux. Trong bài viết này, tôi sẽ giới thiệu cho các bạn cách sử dụng hàm hệ thống pipe () trong Linux. Vậy hãy bắt đầu.

Cú pháp của đường ống() chức năng là:







NSđường ống(NSpipefd[2]);

Ở đây, hàm pipe () tạo ra một kênh dữ liệu một chiều để giao tiếp giữa các quá trình. Bạn vượt qua trong một NS (Số nguyên) kiểu mảng pipefd bao gồm 2 phần tử mảng vào hàm pipe (). Sau đó, hàm pipe () tạo ra hai bộ mô tả tệp trong pipefd mảng.



Phần tử đầu tiên của pipefd mảng, pipefd [0] được sử dụng để đọc dữ liệu từ đường ống.



Phần tử thứ hai của pipefd mảng, pipefd [1] được sử dụng để ghi dữ liệu vào đường ống.





Khi thành công, hàm pipe () trả về 0. Nếu lỗi xảy ra trong quá trình khởi tạo ống, thì hàm pipe () trả về -1.

Hàm pipe () được định nghĩa trong tiêu đề unistd.h . Để sử dụng hàm pipe () trong chương trình C của bạn, bạn phải bao gồm tiêu đề unistd.h như sau:



#bao gồm

Để biết thêm thông tin về chức năng hệ thống pipe (), hãy kiểm tra trang người dùng của pipe () bằng lệnh sau:

$ man2đường ống
Trang người đàn ông của tẩu().

Ví dụ 1:

Đối với ví dụ đầu tiên, hãy tạo một tệp nguồn C mới 1_pipe.c và nhập các dòng mã sau.

#bao gồm
#bao gồm
#bao gồm

NSchủ chốt(vô hiệu) {
NSpipefds[2];

nếu như(đường ống(pipefds) == -1) {
kẻ gian tà ('đường ống');
lối ra (EXIT_FAILURE);
}

printf ('Đọc Giá trị Bộ mô tả Tệp:% d ',pipefds[0]);
printf ('Ghi Giá trị Bộ mô tả Tệp:% d ',pipefds[1]);

trở lạiEXIT_SUCCESS;
}

Ở đây, tôi đã bao gồm tệp tiêu đề của pipe () unistd.h đầu tiên với dòng sau.

#bao gồm

Sau đó, trong chủ chốt() chức năng, tôi đã xác định pipefds mảng số nguyên hai phần tử với dòng sau.

NSpipefds[2];

Sau đó, tôi chạy hàm pipe () để khởi tạo mảng bộ mô tả tệp pipefds như sau.

đường ống(pipefds)

Tôi cũng đã kiểm tra lỗi bằng cách sử dụng giá trị trả về của hàm pipe (). Tôi đã sử dụng lối ra() chức năng kết thúc chương trình trong trường hợp chức năng ống không thành công.

nếu như(đường ống(pipefds) == -1) {
kẻ gian tà ('đường ống');
lối ra (EXIT_FAILURE);
}

Sau đó, tôi in giá trị của bộ mô tả tệp ống đọc và ghi pipefds [0]pipefds [1] tương ứng.

printf ('Đọc Giá trị Bộ mô tả Tệp:% d ',pipefds[0]);
printf ('Ghi Giá trị Bộ mô tả Tệp:% d ',pipefds[1]);

Nếu bạn chạy chương trình, bạn sẽ thấy kết quả sau. Như bạn có thể thấy, giá trị của bộ mô tả tệp ống dẫn đọc pipefds [0]3 và viết bộ mô tả tệp đường ống pipefds [1]4 .

Ví dụ 2:

Tạo một tệp nguồn C khác 2_pipe.c và nhập các dòng mã sau.

#bao gồm
#bao gồm
#bao gồm
#bao gồm

NSchủ chốt(vô hiệu) {
NSpipefds[2];
charđệm[5];

nếu như(đường ống(pipefds) == -1) {
kẻ gian tà ('đường ống');
lối ra (EXIT_FAILURE);
}

char *ghim= '4128 0';

printf ('Đang ghi mã PIN vào đường dẫn ... ');
viết(pipefds[1],ghim, 5);
printf ('Xong. ');

printf ('Đang đọc mã PIN từ đường dẫn ... ');
đọc(pipefds[0],đệm, 5);
printf ('Xong. ');

printf ('PIN từ đường ống dẫn:% s ',đệm);

trở lạiEXIT_SUCCESS;
}

Về cơ bản, chương trình này chỉ cho bạn cách ghi vào đường dẫn và đọc dữ liệu bạn đã ghi từ đường dẫn.

Ở đây, tôi đã lưu trữ mã PIN 4 ký tự vào một char mảng. Độ dài của mảng là 5 (bao gồm cả ký tự NULL 0).

char *ghim= '4128 0';

Mỗi ký tự ASCII có kích thước 1 byte trong C. Vì vậy, để gửi mã PIN 4 chữ số qua đường ống, bạn phải ghi 5 byte (4 + 1 ký tự NULL) dữ liệu vào đường ống.

Để ghi 5 byte dữ liệu ( ghim ) vào đường ống, tôi đã sử dụng viết() chức năng sử dụng bộ mô tả tệp ghi ống dẫn pipefds [1] như sau.

viết(pipefds[1],ghim, 5);

Bây giờ tôi có một số dữ liệu trong đường ống, tôi có thể đọc nó từ đường ống bằng cách sử dụng đọc() chức năng trên bộ mô tả tệp ống dẫn đọc pipefds [0] . Như tôi đã viết 5 byte dữ liệu ( ghim ) vào đường ống, tôi cũng sẽ đọc 5 byte dữ liệu từ đường ống. Dữ liệu đọc được sẽ được lưu trữ trong đệm mảng ký tự. Vì tôi sẽ đọc 5 byte dữ liệu từ ống dẫn, đệm mảng ký tự phải dài ít nhất 5 byte.

Tôi đã xác định đệm mảng ký tự ở đầu chủ chốt() hàm số.

charđệm[5];

Bây giờ, tôi có thể đọc mã PIN từ đường dẫn và lưu trữ nó trong đệm mảng với dòng sau.

đọc(pipefds[0],đệm, 5);

Bây giờ tôi đã đọc mã PIN từ ống dẫn, tôi có thể in nó bằng cách sử dụng printf () hoạt động như bình thường.

printf ('PIN từ đường ống dẫn:% s ',đệm);

Khi tôi chạy chương trình, đầu ra chính xác được hiển thị như bạn có thể thấy.

Ví dụ 3:

Tạo tệp nguồn C mới 3_pipe.c như nhập vào các dòng mã sau đây.

#bao gồm
#bao gồm
#bao gồm
#bao gồm
#bao gồm
NSchủ chốt(vô hiệu) {
NSpipefds[2];
char *ghim;
charđệm[5];

nếu như(đường ống(pipefds) == -1) {
kẻ gian tà ('đường ống');
lối ra (EXIT_FAILURE);
}

pid_t pid=cái nĩa();

nếu như(pid== 0) { // trong tiến trình con
ghim= '4821 0'; // mã PIN để gửi
gần(pipefds[0]); // đóng fd đọc
viết(pipefds[1],ghim, 5); // ghi mã PIN vào đường dẫn

printf ('Tạo mã PIN ở trẻ em và gửi cho phụ huynh ... ');
ngủ(2); // cố ý trì hoãn
lối ra (EXIT_SUCCESS);
}

nếu như(pid> 0) { // trong quá trình chính
đợi đã(VÔ GIÁ TRỊ); // đợi quá trình con kết thúc
gần(pipefds[1]); // đóng ghi fd
đọc(pipefds[0],đệm, 5); // đọc mã PIN từ đường ống dẫn
gần(pipefds[0]); // đóng fd đọc

printf ('Parent đã nhận được mã PIN'% s ' ',đệm);
}

trở lạiEXIT_SUCCESS;
}

Trong ví dụ này, tôi đã chỉ cho bạn cách sử dụng đường ống để giao tiếp giữa các quá trình. Tôi đã gửi mã PIN từ quy trình con đến quy trình mẹ bằng cách sử dụng đường dẫn. Sau đó, đọc mã PIN từ đường dẫn trong quy trình mẹ và in mã đó từ quy trình mẹ.

Đầu tiên, tôi đã tạo một quy trình con bằng cách sử dụng hàm fork ().

pid_t pid=cái nĩa();

Sau đó, trong tiến trình con ( pid == 0 ), Tôi đã viết mã PIN vào đường dẫn bằng cách sử dụng viết() hàm số.

viết(pipefds[1],ghim, 5);

Khi mã PIN được ghi vào đường dẫn từ quy trình con, quy trình mẹ ( pid> 0 ) đọc nó từ đường ống bằng cách sử dụng đọc() hàm số.

đọc(pipefds[0],đệm, 5);

Sau đó, quy trình chính đã in mã PIN bằng cách sử dụng printf () hoạt động như bình thường.

printf ('Parent đã nhận được mã PIN'% s ' ',đệm);

Như bạn có thể thấy, việc chạy chương trình sẽ cho kết quả như mong đợi.

Ví dụ 4:

Tạo tệp nguồn C mới 4_pipe.c như nhập vào các dòng mã sau đây.

#bao gồm
#bao gồm
#bao gồm
#bao gồm
#bao gồm

#define PIN_LENGTH 4
#define PIN_WAIT_INTERVAL 2

vô hiệugetPIN(charghim[PIN_LENGTH+ 1]) {
srand (người lém lỉnh() +có được());

ghim[0] = 49 + hàng ngang () % 7;

(NStôi= 1;tôi<PIN_LENGTH;tôi++) {
ghim[tôi] = 48 + hàng ngang () % 7;
}

ghim[PIN_LENGTH] = ' 0';
}


NSchủ chốt(vô hiệu) {
trong khi(1) {
NSpipefds[2];
charghim[PIN_LENGTH+ 1];
charđệm[PIN_LENGTH+ 1];

đường ống(pipefds);

pid_t pid=cái nĩa();

nếu như(pid== 0) {
getPIN(ghim); // tạo mã PIN
gần(pipefds[0]); // đóng fd đọc
viết(pipefds[1],ghim,PIN_LENGTH+ 1); // ghi mã PIN vào đường dẫn

printf ('Tạo mã PIN ở trẻ em và gửi cho phụ huynh ... ');

ngủ(PIN_WAIT_INTERVAL); // cố tình trì hoãn việc tạo mã PIN.

lối ra (EXIT_SUCCESS);
}

nếu như(pid> 0) {
đợi đã(VÔ GIÁ TRỊ); // đợi con hoàn thành

gần(pipefds[1]); // đóng ghi fd
đọc(pipefds[0],đệm,PIN_LENGTH+ 1); // đọc mã PIN từ đường ống dẫn
gần(pipefds[0]); // đóng fd đọc
printf ('Cha mẹ đã nhận được mã PIN'% s 'từ con. ',đệm);
}
}

trở lạiEXIT_SUCCESS;
}

Ví dụ này giống như Ví dụ 3 . Sự khác biệt duy nhất là chương trình này liên tục tạo ra quy trình con, tạo mã PIN trong quy trình con và gửi mã PIN đến quy trình mẹ bằng cách sử dụng đường ống.

Sau đó, quy trình chính sẽ đọc mã PIN từ đường ống và in ra.

Chương trình này tạo mã PIN_LENGTH mã PIN mới sau mỗi PIN_WAIT_INTERVAL giây.

Như bạn có thể thấy, chương trình hoạt động như mong đợi.

Bạn chỉ có thể dừng chương trình bằng cách nhấn + NS .

Vì vậy, đây là cách bạn sử dụng lệnh gọi hệ thống pipe () trong ngôn ngữ lập trình C. Cảm ơn đã đọc bài viết này.