มีวิธีที่เร็วกว่าในการตรวจสอบว่ามีการใช้งานไฟล์หรือไม่?


8

ฉันกำลังมองหาฟังก์ชันบรรทัดคำสั่งหรือฟังก์ชั่น c ที่จะแจ้งให้ฉันทราบว่าไฟล์เปิด / ใช้งานโดยบางสิ่ง

lsofและfuserบอกสิ่งนี้ แต่พวกเขาให้ข้อมูลอื่น ๆ จำนวนมากซึ่งส่งผลให้ใช้เวลาถึง 300ms ในบางสถานการณ์ (เช่นเมื่อฉันใช้รหัสนี้ใน MAC OS X ฉันกำลังพัฒนาสำหรับ Linux และ OS X) (ฉันมีหน้าต่าง วิธีแก้ปัญหาที่ใช้เวลา 5 มิลลิวินาทีดังนั้นฉันจึงพยายามค้นหาบางสิ่งใน Unix ที่รวดเร็วมากและเพิ่งคืนค่าจริงหรือเท็จหากมีการใช้ไฟล์)


คำตอบ:


9

หากคุณใช้สิ่งนี้เป็นกุญแจล็อคมันจะไม่ทำงานเหมือนlsofหรือfuserป้องกันสภาวะการแข่งขัน

กระบวนการพื้นฐานที่lsofทำคือสืบค้นผ่านกระบวนการทั้งหมดที่/proc/*/fsมองหาตัวอธิบายไฟล์แบบเปิด นี่จะใช้เวลาไม่ว่าคุณจะทำอะไร

คุณสามารถทำสิ่งนี้ได้ด้วยตัวเอง แต่ไม่น่าจะเร็วกว่านี้เพราะคุณต้องตรวจสอบทุกกระบวนการที่เปิดอยู่ในระบบ

หากสิ่งที่คุณกำลังทำคือเวลาที่สำคัญคิดออกอีกวิธีที่จะทำ

  • หากคุณควบคุมไฟล์ผ่านโปรแกรมที่คุณเขียน ใช้ไฟล์ล็อค
  • หากคุณกำลังเรียกใช้คำสั่งบางอย่างที่ทำงานกับไฟล์ให้ดูและดูเอกสารที่คำสั่ง / โปรแกรมเสนอและดูว่ามันไม่สามารถสร้างไฟล์ล็อคได้ ดูว่ามันไม่สามารถสร้างไฟล์ที่มี PID อยู่ภายในได้หรือไม่ จากนั้นคุณสามารถ/proc/<PID>/fsดูว่าไฟล์ของคุณเปิดอยู่หรือไม่ การดูเพียงตัวอธิบายไฟล์ที่เปิดเพียงโพรเซสจะเร็วขึ้นมากจากนั้นทำการแมปข้ามทั้งหมด
  • มิฉะนั้นเพื่อช่วยคุณฉันจะต้องการข้อมูลเพิ่มเติมเกี่ยวกับสิ่งที่คุณกำลังทำ

คุณให้ข้อมูลเพิ่มเติมในความคิดเห็นที่คุณต้องการตรวจสอบว่า Firefox ทำงานในระบบที่กำหนดหรือไม่ วิธีที่ดีที่สุดในการทำเช่นนี้คือค้นหาไฟล์ล็อคของ Firefox สิ่งเหล่านี้ถูกเก็บไว้ในตำแหน่งเริ่มต้นที่ระบุบน Mozilla wiki

ตัวอย่างเช่นบน linux ให้โปรแกรมของคุณทำสิ่งต่อไปนี้:

  • เปิด~/.mozilla/firefox/ไดเรกทอรี
  • รายการไดเรกทอรีทั้งหมดกรองสำหรับไดเรกทอรีที่ลงท้าย.defaultด้วย (ฉันคิดว่าโปรไฟล์ทั้งหมดลงท้ายด้วย.defaultหากไม่เพียงรวบรวมข้อมูลในทุกไดเรกทอรี)
  • ในแต่ละ directory ข้างต้นดูสำหรับการดำรงอยู่ของไฟล์ชื่อหรือlock .parentlockหากคุณเห็นไฟล์หนึ่งหรือทั้งสองไฟล์ Firefox จะเปิดขึ้น

อัลกอริทึมนี้ควรทำงานได้เร็วกว่าสิ่งที่คุณทำบน windows ในปัจจุบัน


คำตอบที่ยอดเยี่ยมขอบคุณ อย่างไรก็ตามมีการบอก lsof และ fuser เพื่อตรวจสอบโฟลเดอร์ pid เท่านั้นถ้าเป็น Firefox หรือไม่ นั่นจะทำให้มันข้ามเนื้อหาทั้งหมดของโฟลเดอร์ยกเว้นโฟลเดอร์ของ firefox (ฉันมี 3 อินสแตนซ์แยกต่างหากดังนั้นนั่นหมายความว่ามันแค่ตรวจสอบ 3 โฟลเดอร์ใช่มั้ย?)
Noitidart

ไฟล์ถูกล็อค แต่ฉันไม่สามารถหาวิธีทดสอบว่าไฟล์ถูกล็อคหรือไม่ มันประสบความสำเร็จในการเปิดอ่าน / เขียน มันแปลกมาก ฉันลอง fcntl จาก c แต่มันกลับมาเสมอ -1 :(
Noitidart

3
@Noitidart คุณกำลังพยายามแก้ไขปัญหาที่แท้จริงของคุณคืออะไร? ในการค้นหาตัวอธิบายไฟล์แบบเปิดของกระบวนการใด ๆ คุณต้องรู้ PID การเปลี่ยนแปลงนี้สำหรับแต่ละอินสแตนซ์ของโปรแกรม วิธีง่ายๆในการได้รับมัน "ด้วยตนเอง" ps aux firefoxอยู่กับ ใช้ PID เหล่านั้นและค้นหาใน/proc/ระบบไฟล์
nixeagle

ps aux firefoxอาขอบคุณครับเป็นความคิดที่ดีเกี่ยวกับ สถานการณ์ของฉันคือ: ฉันมีเส้นทางไปยังไฟล์ มันถูกล็อคถ้า firefox ทำงานอยู่ ฉันต้องการดูว่าล็อคหรือไม่ที่จะบอกว่า Firefox ทำงานอยู่
Noitidart

1
@Noitidart ฉันได้แก้ไขความคิดเห็นของฉันเพื่อรวมวิธีการตรวจหา firefox โดยดูที่ไฟล์ล็อค คุณสามารถทำขั้นตอนนี้ซ้ำในทุกระบบ
nixeagle

1

TL; DR

ในหนึ่งในความคิดเห็นของคุณคุณระบุ:

สถานการณ์ที่แน่นอนของฉันคือฉันมีเส้นทางไปยังไฟล์ มันถูกล็อคถ้า firefox ทำงานอยู่ ฉันต้องการดูว่าล็อคหรือไม่ที่จะบอกว่า Firefox ทำงานอยู่

คำถามดั้งเดิมของคุณเกี่ยวกับ lockfiles ดูเหมือนจะเป็นทางยาวเมื่อมีวิธีที่ง่ายกว่าในการค้นหาว่า Firefox กำลังทำงานอยู่สำหรับผู้ใช้ที่กำหนดหรือไม่และเพื่อตรวจสอบสถานะกระบวนการ

ตรวจสอบสถานะกระบวนการ

วิธีที่เหมาะสมกว่าในการค้นหา PID ของกระบวนการที่กำหนดคือการใช้pgrepจากแพ็คเกจprocps ตัวอย่างเช่น:

$ pgrep -u $LOGNAME firefox
5671

จากนั้นคุณสามารถตรวจสอบสถานะของ PID ด้วยps :

$ ps 5671
  PID TTY      STAT   TIME COMMAND
 5671 ?        Sl   105:47 /usr/lib/firefox/firefox

หรือแค่รับสถานะธงโดยไม่ต้อง cruft อื่น ๆ :

$ ps -ho stat $(pgrep -u $LOGNAME firefox)
Sl

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

รหัสสถานะกระบวนการ

ส่วนประมวลผลสถานะของ ps (1) ให้รายละเอียดความหมายของค่าสถานะต่างๆ บน Ubuntu 14.04 หน้าคนพูดว่า:

PROCESS STATE CODES
       Here are the different values that the s, stat and state output
       specifiers (header "STAT" or "S") will display to describe the state of
       a process:

               D    uninterruptible sleep (usually IO)
               R    running or runnable (on run queue)
               S    interruptible sleep (waiting for an event to complete)
               T    stopped, either by a job control signal or because it is
                    being traced
               W    paging (not valid since the 2.6.xx kernel)
               X    dead (should never be seen)
               Z    defunct ("zombie") process, terminated but not reaped by
                    its parent

       For BSD formats and when the stat keyword is used, additional
       characters may be displayed:

               <    high-priority (not nice to other users)
               N    low-priority (nice to other users)
               L    has pages locked into memory (for real-time and custom IO)
               s    is a session leader
               l    is multi-threaded (using CLONE_THREAD, like NPTL pthreads
                    do)
               +    is in the foreground process group

1
ปัญหาก็คือว่าเขาต้องการที่จะทราบว่าเซสชั่น Firefox เป็นอยู่ในปัจจุบัน. บน Linux ~/.mozilla/firefox/*/lockคุณก็มองหา จากนั้นคุณสามารถระบุเซสชันโดยดูที่ชื่อไดเรกทอรีหลักของแต่ละไฟล์ล็อค บนแพลตฟอร์มอื่น ๆ สิ่งนี้จะไม่ทำงาน การแชทของเราเพิ่มเติมเกี่ยวกับวิธีทำให้มันทำงานบน macs ได้ (ซึ่งไม่เกี่ยวข้องกับอูบุนตู แต่มีอยู่แล้ว) เพื่อความเป็นธรรมเขาควรอัปเดตคำถามให้เจาะจงยิ่งขึ้น : P
nixeagle
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.