Tôi đang triển khai một chương trình giống như trình bao trong C++. Nó có một vòng lặp mà đọc từ cin, dĩa, và chờ đợi cho đứa trẻ.Trong C++, gọi fork khi cin là một bash heredoc gây ra các đoạn đầu vào lặp đi lặp lại
Tính năng này hoạt động tốt nếu đầu vào tương tác hoặc được nhập từ chương trình khác. Tuy nhiên, khi đầu vào là bash heredoc, chương trình sẽ ghi lại các phần của đầu vào (đôi khi vô thời hạn).
Tôi hiểu rằng quy trình con kế thừa các mô tả tệp của cha mẹ, bao gồm bù đắp tệp được chia sẻ. Tuy nhiên, đứa trẻ trong ví dụ này không đọc bất cứ điều gì từ cin, vì vậy tôi nghĩ rằng nó không nên chạm vào bù đắp. Tôi khá lo lắng về việc tại sao điều này lại xảy ra.
test.cpp:
#include <iostream>
#include <unistd.h>
#include <sys/wait.h>
int main(int argc, char **argv)
{
std::string line;
while (std::getline(std::cin, line)) {
pid_t pid = fork();
if (pid == 0) { // child
break; // exit immediately
}
else if (pid > 0) { // parent
waitpid(pid, nullptr, 0);
}
else { // error
perror("fork");
}
std::cout << getpid() << ": " << line << "\n";
}
return 0;
}
tôi biên dịch nó như sau:
g++ test.cpp -std=c++11
Sau đó, tôi chạy nó với:
./a.out <<EOF
hello world
goodbye world
EOF
Output:
012.351.7754: hello world
7754: goodbye world
7754: goodbye world
Nếu tôi thêm một dòng thứ ba foo bar
để lệnh đầu vào, chương trình bị mắc kẹt trong một vòng lặp vô hạn:
13080: hello world
13080: goodbye world
13080: foo bar
13080: o world
13080: goodbye world
13080: foo bar
13080: o world
[...]
phiên bản:
- Linux kernel: 4.4.0 -51-generic
- Ubuntu: 16.04.1 LTS (xenial)
- bash: GNU bash , Phiên bản 4.3.46 (1) -release (x86_64-pc-linux-gnu)
- gcc: g ++ (Ubuntu 5.4.0-6ubuntu1 ~ 16.04.4) 5.4.0 20160609
Điều gì sẽ xảy ra nếu bạn thực hiện 'std :: ios :: sync_with_stdio (false);' ngay từ đầu và sau đó xóa hoàn toàn sau khi bạn viết thành stdout? (ví dụ: thay đổi ''\ n'' thành' std :: endl') – Hurkyl
Bằng cách truy tìm tiến trình con, tôi có thể thấy chính xác những gì đang xảy ra. Quá trình con lseeks ngược về bộ mô tả tập tin 0 trước khi thoát, điều này ảnh hưởng đến tiến trình cha. Thật không may, tôi không biết tại sao thư viện C lại làm điều đó, vì vậy tôi sẽ không đăng các chi tiết như một câu trả lời. Điều này cũng xảy ra với một 'thoát (0)', nhưng không phải '_exit (0);'. –
câu trả lời ở đây có thể hữu ích http://stackoverflow.com/questions/33899548/file-pointers-after-returning-from-a-forked-child-process – Erix