STM

อ่านคู่มือของ Clojure แล้วไม่ค่อยเจอเรื่อง mutex lock แต่ไปเจอ STM (Software Transactional Memory) แทน

พอเข้าไปดูเรื่อง STM ใน Wikipedia  เป็นเรื่องที่เผยแพร่ครั้งแรกโดย Tom Knight ตั้งแต่ค.ศ. 1986 เป็น concurrent control ที่พยายามจะทำให้คล้าย ๆ database transaction แทนที่จะมาใช้ mutex lock แล้วก็พบอีกว่า STM ใช้ได้กับหลายภาษาเลย เพราะทำในระดับ library เอา

พอไปหาต่อใน GitHub  ก็พบว่ามี lib สำหรับทำ STM ใน Rust ด้วย https://github.com/Marthog/rust-stm เข้าไปอ่านดูก็ประมาณว่าพยายามลอกแบบ Haskell มาอีกที แล้วเอา atomic operation มารวม ๆ กันเป็น atomic operation ใหม่ได้ด้วยซึ่งทำตามของ MSR ในปี 2005 (Harris, Tim, et al. “Composable memory transactions.” Proceedings of the tenth ACM SIGPLAN symposium on Principles and practice of parallel programming. ACM, 2005.) อ่านเพิ่มได้จาก https://www.microsoft.com/en-us/research/wp-content/uploads/2005/01/2005-ppopp-composable.pdf

ข้างล่างนี้เป็นตัวอย่างที่ลอกจาก rust-stm มาดัดแปลง comment เอา แน่นอนว่าคงมั่ว ๆ โปรดชี้แนะด้วย

use stm::{atomically, TVar};

// เป็นตัวแปรที่จะ share กันระหว่าง thread
let var = TVar::new(0);

// ใน atomically นี้ผมเข้าใจว่ามันก็คล้าย ๆ begin ... commit ของ SQL 
// ประกันได้ว่า code ในนี้จะไม่ถูกหลาย ๆ thread มาเขียนอ่านสลับกันไปมาสนเสียลำดับ
let x = atomically(|trans| {
    var.write(trans, 42)?; // การใส่ ? คือถ้าเขียนไม่ได้ก็ คือ error ออกไปเลย
    var.read(trans) // พวก var.write var.read นี่น่าจะเป็น atomic operation ที่ว่าเอามารวมกันแบบในงานของ MSR
});

println!("var = {}", x);

เขียนประมาณนี้ก็จะทำให้มั่นใจได้ว่า var.read(trans) ไปอ่านค่า var.write(trans, 42) จาก thread เดียวกันมา ไม่ใช่ไปอ่าน var.write(trans, 42) ของ thread อื่น แต่ว่าตัวอย่างนี้มันคงง่ายไป เพราะว่ายังไงก็ write 42 อยู่แล้วจะ thread ไหนก็คงไม่ต่างกัน

ใน rust-stm วันที่ผมอ่านวันนี้ ข้างในเขาใช้ mutex lock กับ ARC เอาครับมี AtomicUsize ด้วย ที่เห็นคร่าว ๆ คือแค่ละ transaction จะมี BTreeMap เอาไว้เก็บ log ของแต่ละ var: TVar แต่ละตัว เวลาอ่านเขียนอะไรนี่ก็จะไปใส่ log ทั้ง value และบอกด้วยว่าเป็น Read Write ฯลฯ แล้วค่อยไป lock/release เอาตอน commit

แลมันก็น่าจะใช้ง่ายกว่า lock อย่างน้อย ๆ ก็บางกรณี นอกจากนั้นแต่ละ transaction มันก็ทำงานไปก่อนได้เลยโดยเขียนไปใน log โดยที่ไม่ต้องมารอ lock ใน rust-stm ก็มารอกันทีเดียวใน commit เลย แต่ว่าในเอกสารของ Clojure ก็บอกทำนองว่าจะใช้แบบ lock lock-free หรือ hybrid มา implement ก็ยังเป็นประเด็นในงานวิจัยอยู่

Advertisements
This เรื่อง was posted in ไม่มีหมวดหมู่. Bookmark the permalink.

ใส่ความเห็น

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / เปลี่ยนแปลง )

Twitter picture

You are commenting using your Twitter account. Log Out / เปลี่ยนแปลง )

Facebook photo

You are commenting using your Facebook account. Log Out / เปลี่ยนแปลง )

Google+ photo

You are commenting using your Google+ account. Log Out / เปลี่ยนแปลง )

Connecting to %s