Threads by Example (3): Threads semaphore

Dalam artikel ini akan dibahas tentang metode sinkronisasi antar thread menggunakan semaphore. Semaphore ini digunakan untuk menjaga suatu rutin kode sedemikian sehingga hanya satu thread yang bisa mengeksekusinya dalam satu waktu (dalam hal ini semaphore yang digunakan adalah binary semaphore).

Objective

Yang dipelajari:

  1. mengimplementasikan semaphore di thread
  2. inisialisasi semaphore
  3. menggunakan blocking sem_wait
  4. menggunakan non-blocking sem_trywait
  5. menggunakan sem_post
  6. menggunakan sem_getvalue

Threads semaphore

Include file yang digunakan adalah semaphore.h.
Empat fungsi semaphore yang digunakan dalam thread adalah

  1. creation: int sem_init(sem_t *sem, int pshared, unsigned int value)
    sem : semaphore object address
    pshared : apakah semaphore akan dishare dengan process lain? default adalah 0
    value : nilai semaphore inisial
  2. value decrement: int sem_wait(sem_t *sem)
    Fungsi ini secara atomik akan mengurangi nilai semaphore dengan 1. Atomik berarti jika 2 thread berusaha mengurangi nilai semaphore dengan masing-masing 1 secara simultan, maka semaphore akan berkurang dengan 2.
    Jika sem_wait dipanggil saat nilai semaphore > 0, maka eksekusi berikutnya akan dijalankan, sedangkan jika saat dipanggil nilai semaphore=0, fungsi ini akan menunggu sampai thread lain menambah nilai semaphore menjadi > 0
    Jika sem_wait dipanggil oleh 2 thread secara bersamaan, maka jika ada thread lain menambah nilai semaphore dengan 1, hanya 1 thread yang akan melanjutkan eksekusinya dan mengurangi nilai semaphore, yang lain menunggu sampai nilai semaphore bertambah.
    Fungsi sem_wait bersifat blocking, program akan terus menunggu sampai nilai semaphore > 0.
    Terdapat fungsi lain yang non-blocking, yaitu int sem_trywait(sem_t *sem). Fungsi ini akan memberikan output -1 (EAGAIN) jika semaphore = 0.
  3. value increment: int sem_post(sem_t *sem)
    Fungsi ini secara atomik akan menambah nilai semaphore dengan 1.
  4. finishing: int sem_destroy(sem_t *sem)
    Membebaskan resource semaphore. Jika kita menjalankan fungsi ini di saat ada satu thread sedang menunggu, maka akan keluar error.

Kode program

Berikut kode program thread yang menggunakan semaphore. Program akan menunggu masukan dari user, sampai kata ‘end’. Jumlah karakter yang dimasukkan akan ditampilkan. Ada waktu timeout saat user harus memasukkan kata yang pertama, dengan mengimplementasikan non-blocking sem_trywait.

/* Belajar #3: thread_sem.c
 * 
 * Thread semaphore synchronization
 * Compile dengan:
 *    gcc -o thread_sem thread_sem.c -lpthread
 *    (non-blocking) gcc -DNON_BLOCKING -o thread_sem thread_sem.c -lpthread
 * Objective:
 *
 * 1) mengimplementasikan semaphore di thread
 * 2) inisialisasi semaphore
 * 3) menggunakan blocking sem_wait
 * 4) menggunakan non-blocking sem_trywait
 * 5) menggunakan sem_post
 * 6) menggunakan sem_getvalue
 * 
 */

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h> /*for strlen, strncmp*/
#include <pthread.h>
#include <semaphore.h>

void *thread_function(void *arg);
sem_t bin_sem;

#define WORK_SIZE 1024
char work_area[WORK_SIZE];

int main() {
    int res;
    pthread_t a_thread;
    void *thread_result;

    res = sem_init(&bin_sem, 0, 0); /*init semaphore value with 0*/
    if (res != 0) {
        perror("Semaphore initialization failed");
        exit(EXIT_FAILURE);
    }
    /*create thread to display number of typed characters */
    res = pthread_create(&a_thread, NULL, thread_function, NULL);
    if (res != 0) {
        perror("Thread creation failed");
        exit(EXIT_FAILURE);
    }
    printf("Input some text. Enter 'end' to finish\n");
    while(strncmp("end", work_area, 3) != 0) {
        fgets(work_area, WORK_SIZE, stdin);
        sem_post(&bin_sem);
    }
    printf("\nWaiting for thread to finish...\n");
    res = pthread_join(a_thread, &thread_result);
    if (res != 0) {
        perror("Thread join failed");
        exit(EXIT_FAILURE);
    }
    printf("Thread joined\n");
    sem_destroy(&bin_sem); /*destroy semaphore*/
    exit(EXIT_SUCCESS);
}

void *thread_function(void *arg) {
#if defined(NON_BLOCKING)	
    static int sem_value, timeout;
        
    /*Non-blocking*/
	for (timeout=5; timeout>0; timeout-- ) {
		if ( sem_trywait(&bin_sem) != 0 ) {
		   sem_getvalue(&bin_sem, &sem_value);
		   printf("Still waiting input. Semaphore value is %d.\n", sem_value);
		   usleep(1000000);	/*sleep for 1s*/
		} else break; /*we have data*/
	}
	
	/*timeout exceeded*/
	if ( timeout == 0 ) {
		printf("Timeout exceeded. Doing autowrite.\n");
		sprintf(work_area,"You must enter words now.");		
	}	
#else
    sem_wait(&bin_sem);
#endif    
    while(strncmp("end", work_area, 3) != 0) {
        printf("You input %d characters\n", strlen(work_area) -1);
        sem_wait(&bin_sem); /*blocking*/
    }
    pthread_exit(NULL);
}

Hasil keluaran program adalah:

./thread_sem 
Input some text. Enter 'end' to finish
Still waiting input. Semaphore value is 0.
Still waiting input. Semaphore value is 0.
Still waiting input. Semaphore value is 0.
Still waiting input. Semaphore value is 0.
Still waiting input. Semaphore value is 0.
Timeout exceeded. Doing autowrite.
You input 24 characters
Hello
You input 5 characters
end

Waiting for thread to finish...
Thread joined

Referensi

Iklan

One Comment to “Threads by Example (3): Threads semaphore”

  1. Я не понял, тут ПАПКА зарегился, а админов невидно. Админ, одоробло ты тупое, быренько мне доступ открыл ко всем разделам. Сидишь тут дрочишь.
    Чо, перец великий да? Возомнил о себе хер знает чо. Ты глянь на себя: http://cs1268.vkontakte.ru/u28700076/5288632/x_70d1055f.jpg Чо, узнал свою рожу?))
    Эт тоже ты, снял тебя на фотик: http://pics2.pokazuha.ru/p442/k/2/7551620n2k.jpg

Tinggalkan Balasan

Isikan data di bawah atau klik salah satu ikon untuk log in:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s

%d blogger menyukai ini: