Những gì tôi biết về PIPE là nó được sử dụng để liên lạc một chiều, nó giúp liên lạc giữa hai quy trình liên quan. Tôi lấy ví dụ về mã lập trình PIPE sau từ một cuốn sách. Tôi đang cố gắng sử dụng printf
Hiểu mã và in ra tất cả các điểm sau mỗi dòng mã. Nhưng tôi không hiểu chương trình chạy sau mỗi dòng như thế nào. Mã của tôi là như sau:
đường ống:
// sử dụng PIPE để giao tiếp với tiến trình con
#include
#include
#include
/* Viết COUNT bản sao của MESSAGE vào tên tệp, tạm dừng trong giây lát
giữa mỗi */
void writer (thông báo const char*, int count, tên tệp FILE*)
{
for (; đếm > 0 ; -- đếm) {
printf("điểm 13\n");
/* Viết tin nhắn vào tên tệp và gửi đi ngay lập tức.*/
fprintf (tên tập tin, "%s\n", thông báo);
printf("điểm 14\n");
fflush(tên tệp);
printf("điểm 15\n");
/*Ngủ một lát */
ngủ (1);
}
}
/* Đọc các chuỗi ngẫu nhiên từ tên tệp càng lâu càng tốt.
*/
trình đọc trống (tên tệp FILE*)
{
bộ đệm char [1024];
/* Đọc cho đến khi chạm đến cuối tên tệp.
dòng mới hoặc phần cuối của FILE */
printf("điểm 16\n");
while (!feof (tên tệp) && !ferror (tên tệp) && fgets (bộ đệm, sizeof (bộ đệm), tên tệp) != NULL)
fputs (bộ đệm, thiết bị xuất chuẩn);
printf("điểm 17\n");
}
int chính()
{
int fds[2];
pid_t pid;
printf("điểm 1\n");
/* Tạo một bộ mô tả FILE cho hai đầu ống là
được đặt trong fds */
ống(fds);
printf("điểm 2\n");
/* Phân nhánh một tiến trình con */
pid = ngã ba ();
printf("điểm 3\n");
nếu (pid == (pid_t) 0)
{
FILE* tên tệp;
printf("điểm 4\n");
/* Đây là tiến trình con Đóng bản sao của phần cuối ghi của chúng tôi.
bộ mô tả FILE */
đóng (fds[1]);
printf("điểm 5\n");
/* Chuyển đổi bộ mô tả FILE đã đọc thành đối tượng FILE và đọc
từ nó */
tên tệp = fdopen(fds[0], "r");
printf("điểm 6\n");
reader(tên file);
printf("điểm 7\n");
đóng (fds[0]);
printf("điểm 8\n");
}
khác
{
/* Đây là tiến trình gốc */
FILE* tên tệp;
/* Đóng bản sao phần cuối đọc của bộ mô tả FILE */
đóng (fds[0]);
printf("điểm 9\n");
/* Chuyển đổi bộ mô tả ghi FILE thành đối tượng FILE và ghi
với nó */
tên tệp = fdopen(fds[1], "w");
printf("điểm 10\n");
nhà văn ("Tôi muốn học lập trình c!", 5, tên tệp);
printf("điểm 11\n");
đóng (fds[1]);
printf("điểm 12\n");
}
return 0;
}
Tôi thực sự cần phải hiểu mã. Nếu tôi chạy mã của mình thì tôi nhận được kết quả như bên dưới trong thiết bị đầu cuối Linux nhưng tôi không chắc tại sao điểm 9 lại xuất hiện sau điểm 3. Sau điểm 9 tại sao lại là điểm 3, 4, 5, 10. Giải thích chi tiết giúp tôi.
điểm 1
điểm 2
điểm 3
điểm 9
điểm 3
điểm 4
điểm 5
điểm 10
điểm 13
điểm 14
điểm 15
điểm 6
điểm 16
Tôi muốn học lập trình c!
điểm 13
điểm 14
điểm 15
Tôi muốn học lập trình c!
điểm 13
điểm 14
điểm 15
Tôi muốn học lập trình c!
điểm 13
điểm 14
điểm 15
Tôi muốn học lập trình c!
điểm 13
điểm 14
điểm 15
Tôi muốn học lập trình c!
điểm 11
điểm 12
điểm 17
điểm 7
điểm 8
Hàm pipe(int[]) trả về một mảng có kích thước hai số nguyên. Bạn cần hiểu các khái niệm cơ bản ở đây. Ống có thể được sử dụng để liên lạc một chiều như ống nước. Một điều bạn cần hiểu là bên trong một đường ống là một tập tin. Vì vậy, khi chúng ta sử dụng bộ mô tả tệp để đọc hoặc ghi vào một tệp, chúng ta cũng cần một bộ mô tả để đọc/ghi vào một pipe. Bây giờ trong chương trình của bạn, khi thực hiện ống (fds)
Khi , một đường ống được tạo và hai bộ mô tả được tạo để đọc và ghi vào đường ống. Những mô tả này làfds[0]
(mặt đọc) vàfds[1]
(viết cuối).
Bây giờ, đây là những gì bạn cần biếtcái nĩa()
, hàm này tạo một quy trình mới (tiến trình con) bằng cách sao chép một quy trình hiện có. gọi cái nĩa()
Sau đó, thực hiện ngay trong tiến trình con nếu như
,因为 cái nĩa
Trả về 0 trong tiến trình con và điều kiện if không thành công trong tiến trình cha vì cái nĩa
Trả về pid của tiến trình con trong tiến trình cha, vì vậy hãy thực thikhác
. Phần còn lại bạn có thể quan sát mã của bạn.
hiện hữu nếu như
, bạn đang đóng cửa fds[1]
, điều này sẽ khiến quy trình con của bạn bây giờ chỉ đọc bộ mô tả tệp của đường ống và bạn đang đóng fds[0]
Trong phần cha mẹ, điều này sẽ khiến cha mẹ bạn chỉ có bộ mô tả ghi cho đường ống. Bây giờ, con bạn chỉ có thể đọc từ ống và cha mẹ chỉ có thể viết từ ống và bạn có thể quan sát giao tiếp giữa cha mẹ và con cái (cha mẹ đang viết, con đang đọc). Nếu bạn muốn giao tiếp ngược lại, bạn cần tạo một đường ống mới. Vì vậy, một ống có thể được sử dụng để liên lạc theo một hướng.
Bây giờ bạn có thể hiểu phần còn lại của chương trình một cách đơn giản bằng cách hiểu cách các tiến trình cha và con sẽ hoạt động sau khi phân nhánh. Bây giờ, bất kỳ quy trình nào nhận được thời gian CPU để thực thi quy trình đó, bằng cách này, bạn có thể xen kẽ việc thực thi quy trình con và quy trình cha, từ đó nhận được kết quả đầu ra ở trên.
Tôi là một lập trình viên xuất sắc, rất giỏi!