Minggu, 15 Maret 2015

GTK Programming : Membuat Thread dengan GLib


Thread adalah bagian dari proses, namun thread bukanlah proses. Dalam sebuah proses minimal terdapat satu buah thread utama, disebut juga sebagai main thread. Dalam program C, main thread adalah kode yang berada pada fungsi main() sekaligus fungsi-fungsi yang dipanggil dari main().

Thread biasanya dibuat untuk menjalankan tugas lebih cepat, atau digunakan saat ada 2 tugas yang harus dikerjakan secara bersamaan. Misalnya dalam sebuah video player, kita tidak bisa hanya bekerja dengan main thread, setidaknya ada 1 atau 2 lagi thread lainnya. Thread utama untuk menerima input/perintah dari user, thread kedua untuk mengolah suara dan thread ketiga untuk mengolah video. Tentu saja hal ini tidak bisa dilakukan dengan 3 fungsi yang berjalan secara berurutan, ketiganya harus berjalan bersamaan.
 
Dengan membuat thread baru, itu artinya kita membuat fungsi lain berjalan bersamaan dengan fungsi main() dalam waktu yang sama. Dengan berjalan bersamaan, program dapat berjalan lebih cepat. Tapi hal itu bukan berarti akan membuat semuanya lebih mudah.

Program yang menjalankan lebih dari satu thread, harus menjaga agar data global tidak diakses secara bersamaan. Jika tidak, hal yang tak diinginkan dapat terjadi sewaktu-waktu. Sehingga program yang mengimplementasikan multithreading harus mempertimbangkan syncronization primitives.

Kita tidak akan membahas bagaimana mengimplementasikan syncronization primitives. Tapi sekarang kita akan membahas permasalahan thread di GTK yang sangat erat kaitannya dengan multithreading.

Sebuah library dikatakan thread-safe apabila dapat diakses oleh banyak thread secara bersamaan. GTK mungkin aman dipakai untuk banyak program, tetapi rupanya GTK sampai sekarang belum tergolong thread-safe. Jadi, GTK hanya diperbolehkan untuk diakses dari main thread saja.
Semua fungsi callback sebenarnya dieksekusi sebagai bagian dari main thread, jadi jangan kawatir. Lagipula, tidak banyak keperluan berkaitan GTK yang harus diakses melalui thread. Jika ada, maka kita sebaiknya menggunakan idle dan timer untuk melakukannya. Selengkapnya tentang idle dan timer akan dibahas pada kesempatan lain yaa..

Baik, sekarang kita bahas bagaimana membuat thread. Walaupun kita tidak bisa mengakses GTK dari sini, nantinya kita akan menemui banyak sekali hal yang harus dilakukan secara multithreading.
Untuk membuat sebuah thread, gunakan fungsi berikut.


GThread *g_thread_new (const gchar *name, GThreadFunc func, gpointer data);

Fungsi di atas mengembalikan struktur GThread. Struktur ini bersifat opaque, atau tidak bisa diakses secara langsung. Kita hanya perlu tahu bahwa struktur ini berisi tentang informasi thread. Fungsi ini menggunakan 3 argumen, yaitu:
  • name : identitas thread. Digunakan untuk keperluan debug, jadi cukup isikan sesuai dengan keinginan anda. Maksial 16 karakter
  • func : Pointer ke fungsi GThreadFunc, yaitu fungsi yang digunakan sebagai thread.
  • data : Data yang digunakan sebagai argumen pada fungsi GThreadFunc.

GThreadFunc
Berbeda dengan fungsi main thread seperti biasa (int main()). Bentuk fungsi thread yang dibuat harus memiliki bentuk sebagai berikut.

gpointer nama_fungsi (gpointer data);
{
   //lakukan sesuatu
}

Return value bukan berupa int, tapi berupa data dalam bentuk pointer. Untuk mengetahui data yang dikembalikan oleh thread, gunakan fungsi berikut.

gpointer g_thread_join (GThread *thread);


Contoh
#include<gtk/gtk.h>

/* thread ini mengeprint pesan
 * lalu pause/sleep selama 1 detik
 * selama 10 kali
 * setelah itu mengembalikan nilai pointer ke string "abcde"
 */
char *r = "abcde \n";
gpointer thread(gpointer data)
{
    int i;
    for(i=10;i!=0;i--){
        g_print("Pesan dari thread() \n");
        g_usleep(1000000);
    }
    return r;
}

int main(int argc, char *argv[])
{
    GThread *t;
    //buat thread
    t = g_thread_new("mythread", thread,0);
    
    //cetak pesan dan sleep 10x
    int i;
    for(i=10;i!=0;i--)
    {
        g_print("Pesan dari main() \n");
        g_usleep(1000000);
    }
    //dapatkan return value
    g_print("Nilai return dari thread: %s \n",(char *)g_thread_join(t) );
}

Kode di atas juga menunjukkan bagaimana menggunakan fungsi g_usleep(). Fungsi ini digunakan untuk melakukan penundaan/pause dalam kurun waktu sekian microsecond.


void g_usleep (gulong microseconds);

Sekali lagi, ingat, jangan memanggil fungsi GTK dari thread :)

Hasil


Load disqus comments

0 comments