Saya ingin tahu apakah panggilan sistem baca/tulis linux mendukung baca/tulis yang tidak disinkronkan (tulisan yang tidak ditambahkan) ke wilayah yang tidak tumpang tindih dari satu file disk dari banyak utas atau proses. Setiap utas akan mencari wilayah filenya sendiri, dan membaca/menulis dari/ke wilayah ini secara eksklusif, tidak pernah tumpang tindih dengan wilayah tempat utas lain beroperasi.
POSIX menetapkan dalam XSH 2.9.7 bahwa secara substansial semua fungsi I/O bersifat atomik terhadap satu sama lain sehubungan dengan efek yang ditentukan POSIX. Daftar panjang dari fungsi spesifik yang berlaku diberikan, dan open()
, lseek()
, read()
, write()
, dan close()
semua di atasnya. Oleh karena itu,
Jika dua utas masing-masing memanggil salah satu dari fungsi ini, setiap panggilan akan melihat semua efek yang ditentukan dari panggilan lain, atau tidak satu pun.
Itu tidak bergantung pada sinkronisasi eksternal apa pun, bahkan untuk operasi pada deskriptor file yang terkait dengan deskripsi file terbuka yang sama.
Mungkin ada banyak deskripsi file yang terbuka untuk file yang sama, bahkan dalam satu proses (lihat, misalnya, halaman manual untuk open(2)). Diberikan banyak utas yang melakukan read()
dan write()
operasi pada wilayah yang tidak tumpang tindih dari file reguler yang sama, melalui deskriptor file yang mengacu pada deskripsi file terbuka yang berbeda , POSIX tidak memberikan dasar untuk mengharapkan operasi tersebut saling mengganggu, terlepas dari sinkronisasi eksternal dari utas yang terlibat. Dalam praktiknya, ini berfungsi dengan baik.
Di mana Anda bisa mendapat masalah adalah jika utas yang terlibat mencoba menggunakan deskriptor file yang mengacu pada deskripsi file terbuka yang sama. Ini tidak harus memiliki nilai deskriptor file yang sama (jadi dup()
ing deskriptor file tidak membantu di sini), utas juga tidak harus menjadi bagian dari proses yang sama agar situasi muncul. Setiap deskripsi file terbuka memiliki satu posisi file terkait, jadi jika dua utas berbeda mencoba melakukan tugas yang masing-masing memerlukan secara terpisah mengatur offset file dan mentransfer data ke atau dari file, dan jika mereka menggunakan deskripsi file terbuka yang sama, maka atomisitas panggilan fungsi individual tidak cukup untuk memastikan bahwa pembacaan dan penulisan dilakukan pada posisi yang diinginkan. Sinkronisasi diperlukan dalam skenario itu.
Atau, seperti yang diamati @maximegorushkin dalam komentar dan @bk2204 diamati dalam jawaban lain, pread()
dan pwrite()
fungsi melakukan pemosisian dan transfer data dalam satu panggilan. Ini juga ada dalam daftar fungsi I/O atom, dan mereka mengatasi pemisahan pemosisian dari transfer data pada basis per-transfer data. Menggunakannya memerlukan kehati-hatian dan pembukuan ekstra, dan ada skenario yang tidak cukup terlayani, tetapi mungkin tetap layak untuk kasus tertentu yang dipermasalahkan.
Oleh karena itu , jika dua utas berbeda ingin beroperasi pada file yang sama tanpa sinkronisasi, maka pendekatan yang paling aman dan paling umum adalah masing-masing membuka file secara mandiri. Mereka kemudian tidak akan mengganggu satu sama lain selama operasi I/O mereka dibatasi untuk memisahkan wilayah file. Bahkan beroperasi di daerah yang tumpang tindih dari file tidak keluar dari pertanyaan, tetapi itu memperkenalkan pertimbangan khusus aplikasi yang lebih kompleks.
Ya, ini mungkin. pread
dan pwrite
fungsi memungkinkan Anda membaca dan menulis dari file dengan offset tertentu tanpa mengubah offset file. Mereka secara khusus dirancang untuk memungkinkan membaca dan menulis dalam program multithreaded.
Anda harus mencatat bahwa melanggar POSIX, pwrite
pada deskriptor file yang dibuka dengan O_APPEND
akan selalu menulis sampai akhir file.