ملف r / w قفل وإلينبان
-
19-09-2019 - |
سؤال
لدي المشكلة التالية. أريد إنشاء تخزين جلسة تستند إلى نظام الملفات حيث يتم تخزين كل بيانات جلسة في ملف بسيط باسم معرفات الجلسة.
أريد بعد API: write(sid,data,timeout)
, read(sid,data,timeout)
, remove(sid)
حيث SID == اسم الملف، أيضا أريد أن أحصل على نوع من GC الذي قد يزيل كل جلسات مهلة.
مهمة بسيطة للغاية إذا كنت تعمل مع عملية واحدة ولكن دون تافهة تماما عند العمل مع عمليات متعددة أو حتى أكثر من NFS.
أبسط الحل الذي فكرت فيه هو:
write/read:
fd=open(file_name,O_CREAT | O_RDWR); // create a new file or use exsting
fcntl_lock_file(fd)
save data to fd/read data from fd
fcntl_unlock_file(fd)
close(fd)
GC:
fd=open(file_name,O_RDWR);
fcntl_lock_file(fd)
if(timed_out)
unlink(file_name)
fcntl_unlock_file(fd)
close(fd)
المشكلة الأكبر التي تعمل بها الملفات غير المركبة على أسماء الملفات وأقفال الملفات تعمل على واصفات الملفات. لذلك لن يعمل أعلاه في السيناريو التالي:
GC - open,
write - open
GC - lock, unlink, unlock, close // file still exists because held by write
write - lock, write, unlock, close // file removed
هل لدى أي شخص فكرة عن كيفية حل هذه المشكلة؟ هل هناك أي حيل تسمح الجمع بين قفل الملفات وإزالة الملفات أو إجراء عملية ذرية الملف؟
ملاحظات:
- لا أريد استخدام قاعدة البيانات،
- أنا أبحث عن حل ل unix
- يجب أن يعمل الحل مع مكالمات Posix القياسية مثل FCNL، فتح، إغلاق، إلغاء ربط
شكرا.
مسح المشكلة الرئيسية هي أن العملية على الملفات (الأسماء - إلغاء الحظ) يجب أن تتم بحريا مع تشغيل واصفات الملفات - قفل:
- فتح، إلغاء ربط - العمل على الملفات
- FNCTL - العمل في واصفات
المحلول
لن هذا العمل؟
write/read:
fd=open(file_name,O_CREAT | O_RDWR); // create a new file or use exsting
fcntl_lock_file(fd)
if stat(file_name).{st_dev, st_ino} != fstat(fd).{st_dev, st_ino}
unlock, close, retry
save data to fd/read data from fd
fcntl_unlock_file(fd)
close(fd)
إذا stat
يفشل مع Eexist (اسم الملف غير موجود) أو يوضح أن الملف الحالي ليس هو نفسه الذي فتحته بكفالة.