กระบวนการใดเป็น `/ proc / self /` เพื่อ?


40

https://www.centos.org/docs/5/html/5.2/Deployment_Guide/s3-proc-self.html พูดว่า

/proc/self/ไดเรกทอรีคือการเชื่อมโยงกับกระบวนการที่เรียกใช้อยู่

มีหลายกระบวนการที่ทำงานพร้อมกันเสมอดังนั้นกระบวนการใดที่เป็น "กระบวนการที่กำลังทำงานอยู่"?

"กระบวนการที่กำลังทำงานอยู่" มีส่วนเกี่ยวข้องกับกระบวนการใดที่กำลังทำงานอยู่บน CPU ในปัจจุบันโดยพิจารณาจากการสลับบริบทหรือไม่

"กระบวนการที่กำลังทำงานอยู่" นั้นไม่มีส่วนเกี่ยวข้องกับกระบวนการพื้นหน้าและเบื้องหลังหรือไม่?


15
กระบวนการที่ประเมินผล/proc/selfแน่นอน
Charles Duffy

8
คนไหนที่ฉันและฉันหมายถึง?
Jeffrey Bosboom

คำตอบ:


64

สิ่งนี้ไม่เกี่ยวกับกระบวนการพื้นหน้าและเบื้องหลัง มันเกี่ยวข้องกับกระบวนการที่กำลังทำงานอยู่เท่านั้น เมื่อเคอร์เนลที่มีการตอบคำถาม“อะไร/proc/selfชี้ไป?” มันก็หยิบ pid ปัจจุบันกำหนดไว้ , เช่นขั้นตอนการทำงานในขณะนี้ (บน CPU ตรรกะปัจจุบัน) ผลคือ/proc/selfชี้ไปที่ pid ของโปรแกรมที่ถามเสมอ ถ้าคุณวิ่ง

ls -l /proc/self

คุณจะเห็นlspid ของถ้าคุณเขียนรหัสที่ใช้/proc/selfรหัสนั้นจะเห็น pid ของตัวเอง ฯลฯ


13
นี่คือ "ถูกต้อง" ในความหมาย แต่ไม่มีความหมายกับคนที่ไม่เข้าใจแนวคิดของเคอร์เนลของ "ปัจจุบัน" คำตอบที่ดีกว่าคือกระบวนการของการเรียกใช้ระบบโดย/proc/selfเป็นส่วนหนึ่งของชื่อพา ธ ในอาร์กิวเมนต์ตัวใดตัวหนึ่ง
..

1
@R .. นั่นคือสิ่งที่ไฮไลท์คำตอบของ ilkkachu อย่าลังเลที่จะโหวตมัน - ฉันทำแล้ว
Stephen Kitt

36

อันที่เข้าถึง symlink (เรียกว่า readlink () บนมันหรือ open () บนเส้นทางผ่านมัน) มันจะทำงานบน CPU ในเวลานั้น แต่ก็ไม่เกี่ยวข้องกัน ระบบมัลติโปรเซสเซอร์สามารถมีกระบวนการหลายอย่างบน CPU พร้อมกัน

กระบวนการเบื้องหน้าและเบื้องหลังส่วนใหญ่เป็นโครงสร้างของเชลล์และไม่มีกระบวนการพื้นหน้าที่ไม่ซ้ำกันเช่นกันเนื่องจากเชลล์เซสชันทั้งหมดในระบบจะมีหนึ่งกระบวนการ


27

การใช้ถ้อยคำอาจจะดีขึ้น แต่จากนั้นถ้อยคำใด ๆ ที่คุณพยายามเขียนเพื่อแสดงความคิดในการอ้างอิงตนเองจะทำให้เกิดความสับสน ชื่อของไดเรกทอรีนั้นมีความหมายมากกว่าในความคิดของฉัน

โดยทั่วไปหมายถึงกระบวนการที่อ่าน/proc/self/ /proc/self/ดังนั้นถ้าคุณลองเปิด/proc/self/จากโปรแกรม C มันจะแสดงโปรแกรมนั้น หากคุณพยายามที่จะทำมันจากเปลือกแล้วมันเป็นเปลือก ฯลฯ

แต่ถ้าคุณมีซีพียู quad core ที่สามารถทำงาน 4 กระบวนการพร้อมกันสำหรับของจริงไม่ใช่มัลติทาสก์

จากนั้นแต่ละขั้นตอนจะเห็นที่แตกต่างกันจริงโดยไม่มีความสามารถที่จะเห็นแต่ละอื่น ๆ/proc/self//proc/self/

มันทำงานอย่างไร

ดี/proc/self/ไม่ได้จริงๆโฟลเดอร์ เป็นโปรแกรมควบคุมอุปกรณ์ที่เกิดขึ้นเพื่อเปิดเผยตัวเองเป็นโฟลเดอร์หากคุณพยายามเข้าถึง นี่เป็นเพราะมันใช้ API ที่จำเป็นสำหรับโฟลเดอร์ /proc/self/ไดเรกทอรีไม่ได้เป็นเพียงสิ่งเดียวที่ไม่นี้ พิจารณาโฟลเดอร์ที่ใช้ร่วมกันที่เมาท์จากเซิร์ฟเวอร์ระยะไกลหรือติดตั้ง USB thumbdrives หรือ dropbox พวกเขาทั้งหมดทำงานโดยใช้ชุดของ API เดียวกันที่ทำให้พวกเขาทำงานเหมือนโฟลเดอร์

เมื่อกระบวนการพยายามเข้าถึง/proc/self/ไดรเวอร์อุปกรณ์จะสร้างเนื้อหาของมันแบบไดนามิกโดยการอ่านข้อมูลจากกระบวนการนั้น ดังนั้นไฟล์ใน/proc/self/นั้นไม่มีอยู่จริง มันเป็นเหมือนกระจกที่สะท้อนกลับไปที่กระบวนการที่พยายามมองมัน

มันเป็นไดรเวอร์อุปกรณ์จริงๆหรือ คุณฟังดูเหมือนคุณกำลังทำสิ่งต่าง ๆ มากเกินไป!

ใช่มันคือเรื่องจริง ถ้าคุณต้องการที่จะอวดความรู้มันเป็นโมดูลเคอร์เนล แต่ถ้าคุณตรวจสอบการโพสต์ usenet ในช่องทางพัฒนา Linux ต่างๆนักพัฒนาเคอร์เนลส่วนใหญ่ใช้ "ไดรเวอร์อุปกรณ์" และ "โมดูลเคอร์เนล" แทนกัน ฉันเคยเขียนไดรเวอร์อุปกรณ์เอาไว้ ... โมดูลเคอร์เนลสำหรับ Linux หากคุณต้องการเขียนอินเตอร์เฟสของคุณเอง/proc/ตัวอย่างเช่นคุณต้องการ/proc/unix.stackexchange/ระบบไฟล์ที่ส่งคืนโพสต์จากเว็บไซต์นี้คุณสามารถอ่านเกี่ยวกับวิธีการใช้ในหนังสือ "Linux Device Drivers" ที่เผยแพร่โดย O'Reilly มันยังมีให้บริการในรูปแบบ softcopy ออนไลน์


6
/proc/selfไม่ได้เป็นโปรแกรมควบคุมอุปกรณ์ แต่แทนที่จะเป็นส่วนหนึ่งของระบบแฟ้ม AA procfsเคอร์เนลสัมผัสที่เรียกว่า
Chris Down

1
@ChrisDown: ใช่ แต่มันถูกนำไปใช้เป็นโมดูลเคอร์เนล - ซึ่งเป็นไดรเวอร์อุปกรณ์เวอร์ชันของ linux - ยังมีตัวอย่างการนำไปใช้งานของ/procไดร์เวอร์ที่ใช้ในหนังสือที่น่ายกย่อง "Linux Device Drivers" ฉันควรจะรู้ฉันลงเรียนที่วิทยาลัย ฉันอาจใช้คำว่า "เคอร์เนลโมดูล" แทน แต่ "ไดรเวอร์อุปกรณ์" เป็นสิ่งที่คนส่วนใหญ่คุ้นเคยและฉันไม่ต้องการให้ความประทับใจที่ทำให้เข้าใจผิดว่ามีความแตกต่างที่สำคัญระหว่าง "โมดูลเคอร์เนล" และ "ไดรเวอร์อุปกรณ์" นอกเหนือจากคำศัพท์
slebetman

7
@slebetman ดี procfs ไม่ได้เป็นโมดูลต่อ se มันสามารถสร้างขึ้นในไม่เคยสร้างเป็นโมดูล ถ้าคุณต้องการที่จะแยกขนผมที่จะแยกก็คือมันเป็นไดรเวอร์ระบบไฟล์ไม่ใช่ไดรเวอร์ของอุปกรณ์
hobbs

10

มันเป็นกระบวนการใดก็ตามที่เกิดขึ้นกับการเข้าถึง/proc/selfหรือไฟล์ / โฟลเดอร์ในนั้น

ลองcat /proc/self/cmdlineดู คุณจะได้รับแปลกใจแปลกใจcat /proc/self/cmdline(จริง ๆ แล้วแทนที่จะเป็นช่องว่างจะมีตัวละครว่างระหว่างtและ/) เพราะมันจะเป็นกระบวนการที่แมวเข้าถึง pseudofile นี้

เมื่อคุณทำls -l /proc/selfคุณจะเห็น pid ของกระบวนการ ls เอง หรือวิธีการเกี่ยวกับls -l /proc/self/exe; มันจะชี้ไปที่ปฏิบัติการ ls

หรือลองสิ่งนี้เพื่อการเปลี่ยนแปลง:

$ 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

หรือแม้กระทั่ง

$ 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

อย่างที่ฉันบอกว่ามันเป็นกระบวนการใดก็ตามที่เกิดขึ้นกับการเข้าถึง/proc/selfหรือไฟล์ / โฟลเดอร์ในนั้น


2

/ proc / self คือน้ำตาลประโยค มันเป็นทางลัดสำหรับ contatenating / proc / และผลลัพธ์ของ getpid () syscall (สามารถเข้าถึงได้ใน bash เป็น metavariable $$) มันอาจทำให้เกิดความสับสนในกรณีของการเขียนสคริปต์เชลล์เนื่องจากคำสั่งจำนวนมากเรียกใช้กระบวนการอื่นพร้อมด้วย PID ของตัวเอง ... PID ที่อ้างถึงบ่อยครั้งกว่ากระบวนการที่ไม่ทำงาน พิจารณา:

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' จะประเมินเส้นทางไปยังไดเรกทอรีแก้ไขเป็น / proc / 26563 เนื่องจากเป็น PID ของกระบวนการ - กระบวนการที่สร้างขึ้นใหม่ / bin / ls ซึ่งอ่านเนื้อหาของไดเรกทอรี แต่เมื่อถึงเวลาที่กระบวนการถัดไปในไพพ์ไลน์ในกรณีของการเขียนสคริปต์เชลล์หรือตามเวลาที่พรอมต์กลับมาในกรณีของเชลล์เชิงโต้ตอบเส้นทางจะไม่มีอยู่อีกต่อไปและเอาต์พุตข้อมูลหมายถึงกระบวนการที่ไม่มีอยู่

อย่างไรก็ตามจะใช้กับคำสั่งภายนอกเท่านั้น (ไฟล์ที่เป็นไฟล์โปรแกรมที่เรียกใช้งานได้จริงซึ่งต่างจากการสร้างไว้ในเชลล์เอง) ดังนั้นคุณจะได้ผลลัพธ์ที่แตกต่างถ้าคุณใช้ชื่อไฟล์ globbing เพื่อรับรายการเนื้อหาของไดเรกทอรีแทนที่จะส่งชื่อพา ธ ไปยังกระบวนการ / bin / ls ภายนอก:

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

ในบรรทัดแรกเชลล์วางกระบวนการใหม่ '/ bin / ls' ผ่าน exec () syscall ผ่าน "/ proc / self / fd" เป็น argv [1] '/ bin / ls' ในที่สุดก็เปิดไดเรกทอรี / proc / self / fd และอ่านแล้วพิมพ์เนื้อหาในขณะที่มันซ้ำแล้วซ้ำอีกพวกเขา

อย่างไรก็ตามบรรทัดที่สองใช้ glob () ด้านหลังฉากเพื่อขยายรายการชื่อไฟล์ สิ่งเหล่านี้จะถูกส่งเป็นอาร์เรย์ของสตริงเพื่อสะท้อน (โดยปกติจะใช้เป็นคำสั่งภายใน แต่มักจะมี / bin / echo binary ... แต่ส่วนนั้นไม่เกี่ยวข้องจริง ๆ เนื่องจาก echo นั้นเกี่ยวข้องกับสตริงเท่านั้นจึงไม่เคยดึงข้อมูลไปยัง syscall ใด ๆ ที่เกี่ยวข้องกับชื่อพา ธ )

ตอนนี้ให้พิจารณากรณีต่อไปนี้:

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

นี่คือเปลือกที่การปกครองของ / bin / LS ได้ทำไดเรกทอรีย่อยของ proc / A / ตนเองไดเรกทอรีปัจจุบัน ดังนั้นชื่อพา ธ ที่สัมพันธ์กันจะถูกประเมินจากมุมมองของมัน สิ่งที่ดีที่สุดที่ฉันคาดเดาได้คือสิ่งนี้เกี่ยวข้องกับความหมายของไฟล์ POSIX ซึ่งคุณสามารถสร้างฮาร์ดลิงก์หลายลิงก์ไปยังไฟล์รวมถึงตัวอธิบายไฟล์ที่เปิดอยู่ ดังนั้นเวลานี้ / bin / ls จึงทำงานคล้ายกับ echo / proc / $$ / fd / *


-2

เนื่องจากเชลล์เรียกใช้โปรแกรมเช่น ls ในกระบวนการที่แยกกัน / proc / self จะแสดงเป็นsymlinkไปยังnnnnnโดยที่nnnnnเป็น ID กระบวนการของกระบวนการ ls เท่าที่ฉันรู้, เปลือกหอยที่ใช้กันทั่วไปไม่มี builtin สำหรับการอ่าน symlinks แต่ Perl มี:

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

ดังนั้น / proc / self ทำงานเป็น symlink แต่ระบบไฟล์ procfs ทำให้กระบวนการ "น่าอัศจรรย์" ที่ต้องรับรู้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.