Có cách nào nhanh hơn để kiểm tra nếu một tập tin đang được sử dụng?


8

Tôi đang tìm kiếm một chức năng dòng lệnh hoặc chức năng c sẽ cho tôi biết nếu một tập tin được mở / sử dụng bởi một cái gì đó.

lsoffusernói điều này, nhưng họ cung cấp rất nhiều thông tin khác dẫn đến việc mất tới 300ms trong một số trường hợp (như khi tôi sử dụng mã này trên MAC OS X, tôi đang phát triển cho Linux và OS X) (Tôi có một cửa sổ giải pháp mất 5ms vì vậy tôi đang cố gắng tìm thứ gì đó trong Unix cũng rất nhanh và chỉ trả về đúng hoặc sai nếu sử dụng tệp)


Câu trả lời:


9

Nếu bạn đang sử dụng khóa này như một khóa, nó sẽ không hoạt động lsofhoặc fuserkhông ngăn chặn các điều kiện cuộc đua.

Quá trình cơ bản được lsofthực hiện thông qua tất cả các quy trình /proc/*/fstìm kiếm mô tả tệp mở. Điều này sẽ mất thời gian cho dù bạn làm gì.

Bạn có thể tự làm điều này, nhưng nó không có khả năng nhanh hơn vì bạn phải kiểm tra mọi quy trình mở trên hệ thống.

Nếu những gì bạn đang làm là thời gian quan trọng, hãy tìm ra một cách khác để làm điều đó.

  • Nếu bạn kiểm soát tệp thông qua một chương trình mà bạn đã viết; sử dụng một tập tin khóa.
  • Nếu bạn đang chạy một số lệnh hoạt động trên tệp, hãy xem và xem tài liệu nào mà lệnh / chương trình cung cấp và xem liệu nó có thể tạo ra một khóa không. Không, hãy xem nếu nó không thể tạo một tệp có PID bên trong nó. Sau đó, bạn có thể nhìn vào /proc/<PID>/fsđể xem tập tin của bạn hiện đang mở hay không. Nhìn vào chỉ một quá trình mô tả tập tin mở sẽ nhanh hơn nhiều sau đó ánh xạ trên tất cả chúng.
  • Nếu không để giúp bạn, tôi sẽ cần thêm thông tin về những gì bạn đang làm.

Bạn đã cung cấp thêm thông tin trong một nhận xét mà bạn muốn xác định xem Firefox có chạy trên một hệ thống nhất định không. Cách tốt nhất để làm điều này là tìm kiếm các tệp khóa của Firefox. Chúng được lưu trữ ở các vị trí mặc định được chỉ định trên wiki Mozilla.

Ví dụ, trên linux, hãy để chương trình của bạn làm như sau:

  • mở ~/.mozilla/firefox/thư mục lên
  • Liệt kê tất cả các thư mục, lọc cho các thư mục kết thúc bằng .default. (Tôi nghĩ rằng tất cả các cấu hình kết thúc bằng .default, nếu không chỉ thu thập dữ liệu vào mọi thư mục.)
  • Trong mỗi thư mục ở trên, hãy tìm sự tồn tại của một tệp có tên lockhoặc .parentlock. Nếu bạn thấy một hoặc cả hai tệp, Firefox đang mở.

Thuật toán này phải thực thi nhanh hơn những gì bạn làm trên windows hiện tại.


Câu trả lời tuyệt vời cảm ơn bạn. Có cách nào để nói với lsof và fuser chỉ kiểm tra thư mục pid nếu nó là firefox không? Điều đó sẽ khiến nó bỏ qua tất cả nội dung của các thư mục ngoại trừ các thư mục của firefox (Tôi có 3 phiên bản riêng biệt để có nghĩa là nó chỉ kiểm tra 3 thư mục phải không?)
Noitidart

Tệp bị khóa, nhưng tôi không thể tìm ra cách kiểm tra nếu nó bị khóa. Đó là thành công được mở để đọc / viết. Nó rất kì lạ. Tôi đã thử fcntl từ c nhưng nó luôn trả về -1 :(
Noitidart

3
@Noitidart Vấn đề thực sự của bạn mà bạn đang cố gắng giải quyết là gì? Để tra cứu bất kỳ mô tả tệp mở nào của quy trình, bạn phải biết PID của nó. Điều này thay đổi cho từng phiên bản của chương trình. Một cách đơn giản để có được nó "thủ công" là với ps aux firefox. Lấy các PID đó và tìm kiếm chúng trong /proc/hệ thống tập tin.
nixeagle

ah cảm ơn đó là một ý tưởng tốt về ps aux firefox. Vâng, tình huống chính xác của tôi là: Tôi có đường dẫn đến một tập tin. Nó bị khóa nếu firefox đang chạy. Tôi muốn xem nó có bị khóa hay không để biết firefox đang chạy.
Noitidart

1
@Noitidart Tôi đã chỉnh sửa nhận xét của mình để bao gồm cách phát hiện firefox bằng cách xem các tệp khóa. Bạn có thể lặp lại quá trình này trên tất cả các hệ thống.
nixeagle

1

TL; DR

Trong một trong những bình luận của bạn , bạn nêu:

Vâng, tình huống chính xác của tôi là: Tôi có đường dẫn đến một tập tin. Nó bị khóa nếu firefox đang chạy. Tôi muốn xem nó có bị khóa hay không để biết firefox đang chạy.

Câu hỏi ban đầu của bạn về lockfiles có vẻ như là một chặng đường dài khi có nhiều cách dễ dàng hơn để tìm hiểu xem Firefox có đang chạy cho một người dùng nhất định hay không và kiểm tra trạng thái quy trình của nó.

Quy trình kiểm tra nhà nước

Một cách hợp lý hơn để tìm ra PID của một quy trình nhất định là sử dụng pgrep từ gói Procps . Ví dụ:

$ pgrep -u $LOGNAME firefox
5671

Sau đó, bạn có thể kiểm tra trạng thái của PID bằng ps :

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

hoặc chỉ nhận các cờ trạng thái mà không có bất kỳ hành trình nào khác:

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

Một hệ thống của tôi, một lớp lót ở trên luôn chỉ mất 1,4 mili giây để hoàn thành. Số dặm của bạn có thể thay đổi.

Xử lý mã nhà nước

Phần COOCES PROCESS STATE của ps (1) nêu chi tiết ý nghĩa của các cờ trạng thái khác nhau. Trên Ubuntu 14.04, trang người đàn ông nói:

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
vấn đề là anh ta cần biết firefox hiện đang ở phiên nào. Trên linux, bạn chỉ cần tìm ~/.mozilla/firefox/*/lock. Sau đó, bạn có thể xác định phiên bằng cách xem tên thư mục mẹ của từng tệp khóa. Trên các nền tảng khác, điều này không hoạt động. Trò chuyện của chúng tôi đi sâu hơn vào cách làm cho nó hoạt động trên máy Mac (điều này không liên quan đến ubfox, nhưng bạn có nó). Để công bằng, anh ấy thực sự nên cập nhật câu hỏi để cụ thể hơn. : P
nixeagle
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.