Apakah ada cara yang lebih cepat untuk memeriksa apakah suatu file sedang digunakan?

8

Saya mencari fungsi command line atau fungsi c yang akan memberi tahu saya jika file terbuka / sedang digunakan oleh sesuatu.

lsofdan fuserjangan katakan ini, tetapi mereka memberikan banyak info lain yang menghasilkan 300ms dalam beberapa situasi (seperti ketika saya menggunakan kode ini pada MAC OS X, saya devving untuk Linux dan OS X) (saya punya windows solusi yang membutuhkan 5ms jadi saya mencoba untuk menemukan sesuatu di Unix yang juga sangat cepat, dan hanya mengembalikan benar atau salah jika file sedang digunakan)

Noitidart
sumber

Jawaban:

9

Jika Anda menggunakan ini sebagai kunci, itu tidak akan berfungsi sebagai keduanya lsofatau fusermencegah kondisi balapan.

Proses dasar yang lsofdilakukan adalah menjaring seluruh proses /proc/*/fsmencari deskriptor file terbuka. Ini akan memakan waktu, apa pun yang Anda lakukan.

Anda dapat melakukannya sendiri, tetapi sepertinya tidak akan lebih cepat karena Anda harus memeriksa setiap proses terbuka pada sistem.

Jika apa yang Anda lakukan adalah waktu yang kritis, cari cara lain untuk melakukannya.

  • Jika Anda mengontrol file melalui program yang Anda tulis; gunakan file kunci.
  • Jika Anda menjalankan beberapa perintah yang beroperasi pada file, lihat dan lihat dokumentasi apa yang ditawarkan perintah / program dan lihat apakah itu tidak dapat membuat file kunci. Gagal itu, lihat apakah itu tidak dapat membuat file dengan PID di dalamnya. Kemudian Anda dapat /proc/<PID>/fsmelihat apakah file Anda sedang terbuka atau tidak. Melihat hanya satu proses deskriptor file yang terbuka akan jauh lebih cepat daripada memetakan semuanya.
  • Kalau tidak, untuk membantu Anda, saya akan memerlukan lebih banyak informasi tentang apa yang Anda lakukan.

Anda memberi lebih banyak informasi dalam komentar yang ingin Anda tentukan apakah Firefox berjalan pada sistem yang diberikan. Cara terbaik untuk melakukan ini adalah mencari file kunci Firefox. Ini disimpan di lokasi default yang ditentukan pada wiki Mozilla.

Misalnya, di linux, minta program Anda melakukan hal berikut:

  • buka ~/.mozilla/firefox/direktori.
  • Daftar semua direktori, filter untuk direktori yang berakhiran .default. (Saya pikir semua profil diakhiri dengan .default, jika tidak hanya merangkak ke setiap direktori.)
  • Di setiap direktori di atas, cari keberadaan file bernama lockatau .parentlock. Jika Anda melihat satu atau kedua file, Firefox terbuka.

Algoritma ini seharusnya mengeksekusi lebih cepat daripada apa yang Anda lakukan pada windows saat ini.

nixeagle
sumber
Jawaban yang bagus terima kasih. Apakah ada untuk memberitahu lsof dan fuser untuk hanya memeriksa folder pid jika itu firefox? Itu akan membuatnya melewatkan semua isi folder kecuali untuk folder firefox (saya punya 3 instance terpisah sehingga artinya hanya memeriksa 3 folder kan?)
Noitidart
File terkunci, tetapi saya tidak tahu bagaimana cara menguji apakah terkunci. Ini berhasil dibuka untuk membaca / menulis. Ini sangat aneh. Saya mencoba fcntl dari c tetapi selalu kembali -1 :(
Noitidart
3
@Noitidart Apa masalah aktual yang Anda coba selesaikan? Untuk mencari deskriptor file terbuka proses apa pun, Anda harus mengetahui PID-nya. Ini berubah untuk setiap instance program. Cara sederhana untuk mendapatkannya "secara manual" adalah dengan ps aux firefox. Ambil PID tersebut dan cari di sistem /proc/file.
nixeagle
ah terima kasih itu ide yang bagus tentang ps aux firefox. Yah situasi tepatnya saya adalah: Saya memiliki path ke file. Terkunci jika firefox sedang berjalan. Saya ingin melihat apakah terkunci atau tidak memberi tahu apakah firefox sedang berjalan.
Noitidart
1
@Noitidart Saya telah mengedit komentar saya untuk memasukkan cara mendeteksi firefox dengan melihat file kunci. Anda dapat mengulangi proses ini di semua sistem.
nixeagle
1

TL; DR

Dalam salah satu komentar Anda, Anda menyatakan:

Yah situasi tepatnya saya adalah: Saya memiliki path ke file. Terkunci jika firefox sedang berjalan. Saya ingin melihat apakah terkunci atau tidak memberi tahu apakah firefox sedang berjalan.

Pertanyaan awal Anda tentang file penguncian sepertinya jauh ketika ada cara yang lebih mudah untuk mengetahui apakah Firefox berjalan untuk pengguna tertentu, dan untuk memeriksa status prosesnya.

Memeriksa Status Proses

Cara yang lebih masuk akal untuk menemukan PID dari proses yang diberikan adalah dengan menggunakan pgrep dari paket procps . Sebagai contoh:

$ pgrep -u $LOGNAME firefox
5671

Anda kemudian dapat memeriksa status PID dengan ps :

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

atau hanya mendapatkan bendera negara tanpa cacat lainnya:

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

Satu sistem saya, one-liner di atas secara konsisten hanya membutuhkan 1,4 milidetik untuk menyelesaikannya. Jarak tempuh Anda mungkin beragam.

Kode Status Proses

Bagian PROSES STATE CODES dari ps (1) merinci apa arti berbagai bendera negara. Pada Ubuntu 14.04 halaman manual mengatakan:

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
CodeGnome
sumber
1
masalahnya adalah dia perlu tahu di mana sesi firefox saat ini. Di linux, Anda cukup mencari ~/.mozilla/firefox/*/lock. Anda kemudian dapat mengidentifikasi sesi dengan melihat nama direktori induk dari setiap file kunci. Pada platform lain ini tidak berfungsi. Obrolan kami membahas lebih lanjut tentang cara membuatnya bekerja di mac (yang agak tidak relevan untuk ubuntu, tetapi begitulah). Agar adil, ia benar-benar harus memperbarui pertanyaan agar lebih spesifik. : P
nixeagle