ป้องกันการเขียนอ่านไฟล์พร้อมกันด้วย flock

หากมีการเขียนอ่านไฟล์พร้อมๆกัน คุณอาจจะพบกับปัญหานี้แน่นอน นั่นก็คือข้อมูลบางส่วนขาดหายไป เรามาแก้ไขปัญหานี้กันด้วยคำสั่งง่ายๆ ที่มีใน php กันดีกว่าครับ

ปัญหา

คุณจะไม่มีทางพบกับปัญหานี้แน่นอน! ถ้าคุณเขียนสคริปต์ใช้เองคนเดียว หรือถ้าคุณทดสอบสคริปต์ของคุณคนเดียว
ปัญหานี้มักจะเกิดเวลาสคริปต์ของคุณต้องทำงานร่วมกับโปรแกรมอื่นๆ ที่มีโอกาสอ่านเขียนไฟล์พร้อมๆ กัน หรือบางครั้งอาจจะเป็นสคริปต์ด้วยกันเอง

ขอสมมติ ให้มีโปรแกรม 2 โปรแกรม ได้แก่โปรแกรม A และโปรแกรม B
โปรแกรม A จะอ่านไฟล์ abc.txt แล้วเขียนข้อความ AA ต่อท้าย
ส่วนโปรแกรม B จะอ่านไฟล์ abc.txt แล้วเขียนข้อความ BB ต่อท้าย
สมมติให้ตอนแรก ไฟล์ abc.txt มีข้อความอยู่ว่า cccc

ถ้าเราเรียกให้โปรแกรม A และโปรแกรม B ทำงานทีละโปรแกรม ไฟล์ abc.txt ควรจะมีข้อความว่า ccccAABB
แต่เมื่อนำไปใช้งานจริงแล้วมีผู้ใช้เรียกโปรแกรม A และ B พร้อมๆ กัน ก็จะเกิดปัญหาตามรูปข้างล่างครับ

จะเห็นว่าโปรแกรมทั้งสองทำงานตามปกติครับ อ่านไฟล์มาเก็บในตัวแปร แล้วเพิ่มข้อความเข้าไปข้างท้าย แล้วก็เขียนไฟล์กลับเหมือนเดิม
ปัญหาที่เจอตอนนี้ก็คือ โปรแกรม A และ โปรแกรม B ไม่ได้อ่านไฟล์ abc.txt ล่าสุดไว้ ทำให้ การแก้ไขของอีกโปรแกรมหนึ่งหายไป
จากภาพด้านบนจะเห็นว่า การทำงานของโปรแกรม B ไม่มีผลอะไรกับไฟล์ abc.txt เลย

แล้วเราจะแก้ไขปัญหานี้ยังไงดี?

flock : พระเอกตัวจริงมานี่แล้ว

ปัญหาเหล่านี้จะหมดไป (เหรอ?) ปัญหาอาจจะไม่หมดไป แต่จะช่วยแก้ปัญหาการอ่าน/เขียนไฟล์พร้อมกันให้
โดยฟังก์ชั่นนี้จะทำการใส่กุญแจ (Lock) ไฟล์ที่กำลังอ่านหรือเขียนอยู่ เพื่อป้องกันไม่ให้โปรแกรมอื่นมาเขียนหรืออ่านไฟล์พร้อมๆ กับเรา

วิธีการใช้งาน flock

สมมติเรามีโปรแกรมที่กำลังเขียนไฟล์ดังนี้

<?
      // write file
      $fp = fopen("abc.txt", "w");
 
      fwrite($fp, "blah blah");
      fclose($fp);
?>

เราสามารถปรับปรุงให้โปรแกรมนี้ดีขึ้น โดยการใช้คำสั่ง flock (น่าจะย่อมาจาก File Lock นะ) เข้าไป ตามนี้ครับ

<?
 
      // write file
      $fp = fopen("abc.txt", "w");
      flock($fp, LOCK_EX); // lock ไฟล์นี้ไว้เพื่อเขียน ข้อความลงไป
 
      fwrite($fp, "blah blah");
      flock($fp, LOCK_UN); // unlock ไฟล์นี้เพื่อให้โปรแกรมอื่นสามารถเขียนไฟล์นี้ได้บ้าง
      fclose($fp);
 
?>

ประโยชน์ของการใช้ flock คือ เราสามารถ lock ไม่ให้โปรแกรมอื่นๆ (ถึงแม้จะไม่ใช่สคริปต์ php เขียนไฟล์นี้พร้อมๆ กับเราได้ครับ)

รายละเอียดของคำสั่ง flock

รูปแบบการใช้งาน : flock(ไฟล์พอยเตอร์, operation);
เราสามารถกำหนด operation ให้กับ flock ได้ดังนี้

  • Lock ไฟล์ เพื่ออ่าน ให้กำหนดเป็น LOCK_SH
  • Lock ไฟล์ เพื่อเขียน ให้กำหนดเป็น LOCK_EX
  • ปลด Lock ไฟล์ ให้โปรแกรมอื่นใช้ได้ ให้กำหนดเป็น LOCK_UN

Post new comment

คำนวณผลบวกด้านบนแล้วกรอกผลลัพธ์ลงในช่อง เช่น 2 ลบ 1 ให้พิมพ์ 1