2011-12-14 40 views
12

Đây là một câu hỏi rất cơ bản mà tôi có. Trong bài giảng của giáo sư của tôi, có một ví dụ tôi không thực sự nhận được.C I/O chuẩn và UNIX cơ bản I/O

Cô đã viết:

printf("u"); 
write(STDOUT_FILENO, "m", 1); 
printf("d\n"); 

... và cô ấy nói đặt ra của mã này sẽ là:

bùn

Tôi không nhận được nó. Vì vậy, nếu có ai hiểu tại sao điều này xảy ra, hãy giải thích cho tôi. (. Trong lần thứ hai trang trượt cuối cùng):

tham khảo câu hỏi này

http://lagoon.cs.umd.edu/216/Lectures/lect17.pdf 

Trả lời

20

write là cuộc gọi hệ thống - được thực hiện bởi giao diện giữa chế độ người dùng (nơi các chương trình giống như bạn chạy) và hạt nhân hệ điều hành (xử lý ghi thực tế vào đĩa khi byte được ghi vào tệp).

printf là chức năng thư viện chuẩn C - nó được triển khai bằng mã thư viện được tải vào chương trình chế độ người dùng của bạn.

Chức năng đầu ra của thư viện chuẩn C đệm đầu ra của chúng, theo mặc định cho đến khi đạt đến cuối dòng. Khi bộ đệm đầy hoặc chấm dứt với một dòng mới, nó được ghi vào tập tin thông qua một cuộc gọi đến write từ việc thực hiện thư viện.

Do đó, đầu ra qua printf không được gửi đến hệ điều hành write ngay lập tức. Trong ví dụ của bạn, bạn đệm chữ 'u', sau đó ngay lập tức viết chữ 'm', sau đó nối "d \ n" vào bộ đệm và thư viện chuẩn làm cho cuộc gọi write(STDOUT_FILENO, "ud\n");

+0

+1 để được giải thích chi tiết. – hari

+0

Tôi hiểu rồi! –

10

Theo mặc định, stdoutdòng đệm; nó không được flushed cho đầu ra cho đến khi nó gặp một ký tự newline (hoặc cho đến khi buffer đầy lên).

Vì vậy, "u" nằm trong bộ đệm cho đến khi nhận được "d\n". Nhưng write bỏ qua bộ đệm này.

+0

Tôi không nói rằng viết "subverts "bất cứ điều gì. Bộ đệm còn nguyên vẹn và hoạt động tốt. Chính xác hơn, viết là một cuộc gọi hệ thống và printf là một hàm thư viện. –

+0

@Heath: "bypasses", sau đó! –

+2

stdout là * không * dòng đệm theo mặc định. * if * stdout được liên kết với một tty, sau đó nó là dòng đệm theo mặc định. Nếu stdout là một tập tin thường xuyên hoặc một đường ống (hoặc thực sự bất cứ điều gì khác hơn là một tty) nó sẽ được chặn theo mặc định. –

Các vấn đề liên quan