Mutex Programming
การจัดจังหวะการทำงานของเทรด (Thread Synchronization)
Mutex lock (MUTual EXclusion lock) เป็น Semaphore อย่างง่ายที่นำมาใช้ในการจัดการ Mutual Exclusion กับทรัพยากรที่ถูกใช้งานร่วมกันได้อย่างมีประสิทธิภาพโดยเฉพาะกับ thread โดย Mutex จะเป็นตัวแปรที่มีได้ 2 สถานะ คือ สถานะปลดล็อค (unlock
) หรือ สถานะล็อค (lock
) ซึ่งใช้เพียง 1 บิต (1-bit) ที่แสดงสถานะของมัน แต่ในทางปฏิบัติเราใช้ตัวแปรจำนวนเต็ม (integer) โดยให้สถานะ unlocked
เป็นเลขศูนย์ และสถานะ lock
จะใช้เลขอื่นแทน

นักพัฒนาสามารถพัฒนาโปรแกรมโดยเรียกใช้ความสามารถในการจัดกลไกการทำงานประสานกันระหว่างเทรด (synchronization mechanisms) โดยไม่ให้เกิดปัญหาในกรณีที่เทรดแต่ละตัวจะต้องเข้าไปใช้ทรัพยากรตัวเดียวกัน ภายในเครื่องคอมพิวเตอร์เดียวกันโดยใช้ไลบรารี pthread ซึ่งจากรูปด้านบนแสดงการอนุญาตเพียง thread #1 ตัวเดียวที่สามารถเข้าไปกำหนดค่า mutex (Mutual Exclusion Lock) เพื่อเข้าถึงทรัพยากรหรือตัวแปร โดยที่ thread #2 จะต้องรอ (block) คิวเพื่อเข้าถึงทรัพยากรหรือตัวแปรหลังจากที่ thread #1 ทำงานเสร็จเรียบร้อยแล้ว ตัว thread #2 จึงจะสามารถเข้าไปกำหนดค่า mutex เพื่อขอเข้าถึงทรัพยากรหรือตัวแปรนั้นต่อไป
แต่อย่างไรก็ตามการใช้ mutex จะถูกใช้ได้เพียงในกรณีมีหลายเทรดในโปรเซสตัวเดียวกันเท่านั้น แต่ในกรณีที่มีหลายโปรเซสต้องการเข้าใช้ทรัพยากรเดียวกัน จะต้องแก้ไขโดยการใช้เทคนิค semaphore แทน mutex ซึ่งจะกล่าวในหัวข้อ 6.2.3 ต่อไป

ตัวอย่างแสดงการสร้างเทรดจำนวน 10 เทรด โดยแต่ละตัวจะเข้าไปใช้งานตัวแปรกลางชื่อว่า counter แต่จะต้องเพิ่มค่า counter ได้เพียงครั้งละ 1 เทรดเท่านั้น
// simple_mutex.c
#include <stdio.h>
#include <pthread.h>
#define NTHREADS 10
void* thread_function(void*);
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
int counter = 0;
main() {
pthread_t thread_id[NTHREADS];
int i, j;
for (i = 0; i < NTHREADS; i++) {
pthread_create(&thread_id[i], NULL, thread_function, NULL);
}
for (j = 0; j < NTHREADS; j++) {
pthread_join(thread_id[j], NULL);
}
// Now that all threads are complete I can print the final result.
// Without the join I could be printing a value before all the threads
// have been completed.
printf("Final counter value: %d\n", counter);
}
void* thread_function(void *dummyPtr) {
printf("Thread number %ld\n", pthread_self());
pthread_mutex_lock(&mutex1);
counter++;
pthread_mutex_unlock(&mutex1);
}
คอมไพล์ และทดสอบรันโปรแกรม
$ gcc -o simple_mutex simple_mutex.c –lpthread
$ ./simple_mutex
Thread number 139638417069824
Thread number 139638425462528
Thread number 139638442247936
Thread number 139638433855232
Thread number 139638408677120
Thread number 139638400284416
Thread number 139638391891712
Thread number 139638383499008
Thread number 139638375106304
Thread number 139638366713600
Final counter value: 10
Last updated
Was this helpful?