Quá trình nào là `/ Proc / self /` cho?


40

https://www.centos.org/docs/5/html/5.2/Deployment_Guide/s3-proc-elf.html nói

Thư mục /proc/self/là một liên kết đến quá trình hiện đang chạy.

Luôn có nhiều quy trình chạy đồng thời, vậy quy trình nào là "quy trình hiện đang chạy"?

"Quá trình hiện đang chạy" có liên quan gì đến quá trình hiện đang chạy trên CPU không, xem xét chuyển đổi ngữ cảnh?

"Quá trình hiện đang chạy" không liên quan gì đến các quy trình nền trước và nền?


15
Quá trình đánh giá /proc/self, tất nhiên.
Charles Duffy

8
Những người làm tôitôi tham khảo?
Jeffrey Bosboom

Câu trả lời:


64

Điều này không có gì để làm với các quá trình nền trước và nền; nó chỉ phải làm với quá trình hiện đang chạy. Khi kernel phải trả lời câu hỏi thì điều gì /proc/selftrỏ đến?, Nó chỉ đơn giản chọn pid được lên lịch hiện tại , tức là quá trình hiện đang chạy (trên CPU logic hiện tại). Hiệu quả là /proc/selfluôn luôn chỉ ra pid của chương trình yêu cầu; Nếu bạn chạy

ls -l /proc/self

bạn sẽ thấy lspid, nếu bạn viết mã sử dụng /proc/selfmã đó sẽ thấy pid của chính nó, v.v.


13
Điều này là "chính xác" theo một nghĩa nào đó, nhưng không có ý nghĩa đối với người không hiểu khái niệm "hiện tại" của hạt nhân. Một câu trả lời tốt hơn sẽ là quá trình thực hiện cuộc gọi hệ thống với /proc/selftư cách là một phần của tên đường dẫn trong một trong các đối số của nó.
R ..

1
@R .. đó là những gì câu trả lời nổi bật của ilkkachu, vui lòng nêu lên câu trả lời đó - Tôi đã làm.
Stephen Kitt

36

Người truy cập symlink (gọi readlink () trên đó hoặc open () trên đường dẫn qua nó). Nó sẽ chạy trên CPU vào thời điểm đó, nhưng điều đó không liên quan. Một hệ thống đa bộ xử lý có thể có một số quy trình trên CPU cùng một lúc.

Các quy trình nền trước và nền chủ yếu là một cấu trúc shell và cũng không có quy trình nền trước duy nhất, vì tất cả các phiên shell trên hệ thống sẽ có một.


27

Từ ngữ có thể tốt hơn nhưng một lần nữa, bất kỳ từ ngữ nào bạn cố gắng soạn để thể hiện ý tưởng tự tham khảo sẽ gây nhầm lẫn. Tên của thư mục là mô tả nhiều hơn theo ý kiến ​​của tôi.

Về cơ bản, /proc/self/đại diện cho quá trình đọc /proc/self/. Vì vậy, nếu bạn cố gắng mở /proc/self/từ một chương trình C thì nó đại diện cho chương trình đó. Nếu bạn cố gắng làm nó từ vỏ thì đó là vỏ v.v.

Nhưng nếu bạn có CPU lõi tứ có khả năng chạy 4 tiến trình đồng thời, thực tế chứ không phải đa nhiệm thì sao?

Sau đó, mỗi quá trình sẽ thấy khác nhau /proc/self/thực sự mà không thể nhìn thấy nhau /proc/self/.

Cái này hoạt động ra sao?

Chà, /proc/self/thật ra không phải là một thư mục. Đó là một trình điều khiển thiết bị xảy ra để lộ chính nó như một thư mục nếu bạn cố gắng truy cập nó. Điều này là do nó triển khai API cần thiết cho các thư mục. Thư mục /proc/self/không phải là thứ duy nhất làm điều này. Xem xét các thư mục được chia sẻ được gắn từ các máy chủ từ xa hoặc gắn các ổ USB hoặc hộp nhỏ. Tất cả đều hoạt động bằng cách triển khai cùng một bộ API khiến chúng hoạt động giống như các thư mục.

Khi một quá trình cố gắng truy cập /proc/self/trình điều khiển thiết bị sẽ tự động tạo nội dung của nó bằng cách đọc dữ liệu từ quá trình đó. Vì vậy, các tập tin trong /proc/self/không thực sự tồn tại. Nó giống như một tấm gương phản chiếu lại quá trình cố gắng nhìn vào nó.

Nó thực sự là một trình điều khiển thiết bị? Bạn có vẻ như bạn đang quá đơn giản hóa mọi thứ!

Vâng, nó thực sự là. Nếu bạn muốn trở thành mô phạm thì đó là mô-đun hạt nhân. Nhưng nếu bạn kiểm tra các bài đăng usenet trên các kênh nhà phát triển Linux khác nhau, hầu hết các nhà phát triển kernel sử dụng "trình điều khiển thiết bị" và "mô-đun hạt nhân" có thể hoán đổi cho nhau. Tôi đã từng viết trình điều khiển thiết bị, err ... các mô-đun kernel, cho Linux. Nếu bạn muốn viết giao diện của riêng mình /proc/, ví dụ bạn muốn có một /proc/unix.stackexchange/hệ thống tệp trả về các bài đăng từ trang web này, bạn có thể đọc về cách thực hiện trong cuốn sách "Trình điều khiển thiết bị Linux" đáng kính do O'Reilly xuất bản. Nó thậm chí còn có sẵn dưới dạng softcopy trực tuyến.


6
/proc/selfkhông phải là trình điều khiển thiết bị, mà thay vào đó là một phần của hệ thống tập tin tiếp xúc với kernel được gọi procfs.
Chris Down

1
@ChrisDown: Có nhưng nó được triển khai như một mô-đun hạt nhân - phiên bản trình điều khiển thiết bị của linux - thậm chí còn có một ví dụ về /proctrình điều khiển dựa trên cuốn sách đáng kính "Trình điều khiển thiết bị Linux". Tôi nên biết, tôi đã thực hiện một trong trường đại học. Có lẽ tôi đã có thể sử dụng thuật ngữ "mô-đun hạt nhân" nhưng "trình điều khiển thiết bị" là thứ mà hầu hết mọi người quen thuộc và tôi không muốn tạo ấn tượng sai lệch rằng có một sự khác biệt đáng kể giữa "mô-đun hạt nhân" và "trình điều khiển thiết bị" ngoài thuật ngữ.
slebetman

7
@slebetman tốt, Procfs không phải là một mô-đun, nó chỉ có thể được xây dựng, không bao giờ được xây dựng như một mô-đun. Nếu bạn muốn chia tóc, tóc cần chia là trình điều khiển hệ thống tệp chứ không phải trình điều khiển thiết bị
hobbs

10

Đó là bất kỳ quá trình nào xảy ra để truy cập /proc/selfhoặc các tập tin / thư mục trong đó.

Hãy thử cat /proc/self/cmdline. Bạn sẽ nhận được, ngạc nhiên bất ngờ, cat /proc/self/cmdline(thực ra, thay vì một khoảng trắng sẽ có một ký tự null giữa t/) bởi vì đó sẽ là quá trình con mèo truy cập vào tệp giả này.

Khi bạn làm một ls -l /proc/self, bạn sẽ thấy pid của quá trình ls chính nó. Hoặc làm thế nào về ls -l /proc/self/exe; nó sẽ trỏ đến ls thực thi.

Hoặc thử điều này, để thay đổi:

$ cp /proc/self/cmdline /tmp/cmd
$ hexdump -C /tmp/cmd
00000000  63 70 00 2f 70 72 6f 63  2f 73 65 6c 66 2f 63 6d  |cp./proc/self/cm|
00000010  64 6c 69 6e 65 00 2f 74  6d 70 2f 63 6d 64 00     |dline./tmp/cmd.|
0000001f

hoặc thậm chí

$ hexdump -C /proc/self/cmdline 
00000000  68 65 78 64 75 6d 70 00  2d 43 00 2f 70 72 6f 63  |hexdump.-C./proc|
00000010  2f 73 65 6c 66 2f 63 6d  64 6c 69 6e 65 00        |/self/cmdline.|
0000001e

Như tôi đã nói, đó là bất kỳ quá trình nào xảy ra để truy cập /proc/selfhoặc các tập tin / thư mục trong đó.


2

/ Proc / self là cú pháp đường. Đó là một lối tắt để liên kết / Proc / và kết quả của tòa nhà getpid () (có thể truy cập trong bash dưới dạng biến thái $$). Nó có thể gây nhầm lẫn, trong trường hợp kịch bản shell, vì nhiều câu lệnh gọi các quy trình khác, hoàn thành với các bộ vi xử lý riêng ... Các bộ quy tắc đề cập đến, thường xuyên hơn là các quy trình chết. Xem xét:

root@vps01:~# ls -l /proc/self/fd
total 0
lrwx------ 1 root root 64 Jan  1 01:51 0 -> /dev/pts/0
lrwx------ 1 root root 64 Jan  1 01:51 1 -> /dev/pts/0
lrwx------ 1 root root 64 Jan  1 01:51 2 -> /dev/pts/0
lr-x------ 1 root root 64 Jan  1 01:51 3 -> /proc/26562/fd
root@vps01:~# echo $$
593

'/ bin / ls' sẽ đánh giá đường dẫn đến thư mục, giải quyết nó là / Proc / 26563, vì đó là PID của quy trình - quy trình mới được tạo / bin / ls - đọc nội dung của thư mục. Nhưng tại thời điểm quy trình tiếp theo trong đường ống, trong trường hợp kịch bản lệnh shell hoặc vào thời điểm dấu nhắc quay lại, trong trường hợp trình bao tương tác, đường dẫn không còn tồn tại và đầu ra thông tin đề cập đến quy trình không tồn tại.

Tuy nhiên, điều này chỉ áp dụng cho các lệnh bên ngoài (những lệnh là các tệp chương trình thực thi thực tế, trái ngược với việc được tích hợp vào chính trình bao). Vì vậy, bạn sẽ nhận được các kết quả khác nhau nếu bạn nói, sử dụng tên tệp toàn cầu để lấy danh sách nội dung của thư mục, thay vì chuyển tên đường dẫn đến tiến trình / bin / ls bên ngoài:

root@vps01:~# ls /proc/self/fd
0  1  2  3
root@vps01:~/specs# echo /proc/self/fd/*
/proc/self/fd/0 /proc/self/fd/1 /proc/self/fd/2 /proc/self/fd/255 /proc/self/fd/3

Trong dòng đầu tiên, shell đã tạo ra một quy trình mới, '/ bin / ls', thông qua tòa nhà exec (), truyền "/ Proc / self / fd" như argv [1]. Lần lượt '/ bin / ls', mở thư mục / Proc / self / fd và đọc, sau đó in, nội dung của nó khi nó lặp đi lặp lại trên chúng.

Tuy nhiên, dòng thứ hai sử dụng global () đằng sau hậu trường để mở rộng danh sách tên tệp; chúng được truyền dưới dạng một chuỗi các chuỗi để lặp lại. (Thường được triển khai như một lệnh nội bộ, nhưng thường cũng có nhị phân / bin / echo ... nhưng phần đó thực sự không liên quan, vì echo chỉ xử lý các chuỗi mà nó không bao giờ cung cấp cho bất kỳ tòa nhà nào liên quan đến tên đường dẫn.)

Bây giờ, hãy xem xét trường hợp sau:

root@vps01:~# cd /proc/self/fd
root@vps01:~# ls
0  1  2  255

Ở đây, shell, tiến trình cha của / bin / ls, đã tạo một thư mục con của / Proc / self thư mục hiện tại của nó . Do đó, tên đường dẫn tương đối được đánh giá từ quan điểm của nó. Tôi đoán tốt nhất là điều này có liên quan đến ngữ nghĩa tệp POSIX nơi bạn có thể tạo nhiều liên kết cứng đến một tệp, bao gồm mọi mô tả tệp mở. Vì vậy, lần này, / bin / ls hoạt động tương tự như echo / Proc / $$ / fd / *.


-2

Vì shell gọi các chương trình như ls trong các quy trình riêng biệt, / Proc / self sẽ hiển thị dưới dạng liên kết tượng trưng đến nnnnn , trong đó nnnnn là ID tiến trình của quy trình ls. Theo như tôi biết, các shell thường được sử dụng không có nội dung để đọc các liên kết tượng trưng, ​​nhưng Perl có:

perl -e 'print "/ Proc / self link:", readlink ("/ Proc / self"), "- pid $$ \ n";'

Vì vậy, / Proc / self hoạt động như một liên kết tượng trưng, ​​nhưng hệ thống tập tin Procfs làm cho nó nhận thức được quy trình "kỳ diệu".

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.