Selamat Datang Di Anak Jadul Ingin Pintar (AJIP)

Thread, SMP, dan Microkernel

Selasa, 16 Oktober 20120 komentar


Secara informal; proses adalah program dalam eksekusi. Suatu proses adalah lebih dari kode program, dimana kadang kala dikenal sebagai bagian tulisan. Proses juga termasuk aktivitas yang sedang terjadi, sebagaimana digambarkan oleh nilai pada program counter dan isi dari daftar prosesor/ processor’s register. Suatu proses umumnya juga termasuk process stack, yang berisikan data temporer (seperti parameter metoda, address yang kembali, dan variabel lokal) dan sebuah data section, yang berisikan variabel global.

Thread adalah sebuah alur kontrol dari sebuah proses. Suatu proses yang multithreaded mengandung beberapa perbedaan alur kontrol dengan ruang alamat yang sama. Keuntungan dari multithreaded meliputi peningkatan respon dari user, pembagian sumber daya proses, ekonomis, dan kemampuan untuk mengambil keuntungan dari arsitektur multiprosesor. User level thread adalah thread yang tampak oleh programmer dan tidak diketahui oleh kernel. User level thread secara tipikal dikelola oleh sebuah library thread di ruang user. Kernel level thread didukung dan dikelola oleh kernel sistem operasi.

Konsep Proses

• Kepemilikan resource:
– Process memerlukan ruang alamat virtual untuk menyimpan process image
– Process image = program + data + stack + PCB
– Unit terkecil yang dapat memiliki resource adalah proses atau task
– Resource = memori, I/O channel, I/O device, file, CPU, dll
• Penjadualan/eksekusi:
– Mengikuti jalur eksekusi (trace)
– Eksekusi suatu proses bisa secara interleaving (selang-seling) dengan proses lain
– Thread = pecahan dari suatu proses yang dapat dijadualkan atau dieksekusi = lightweight process (LWP)

Multithreading
• Merupakan kemampuan sistem operasi dalam mengeksekusi banyak thread yang berasal dari sebuah proses
• OS tradisional:
– Satu proses hanya terdiri dari satu thread
– MS-DOS: hanya satu proses dan tiap proses hanya satu thread
– UNIX tradisional: banyak proses, tetapi tiap proses hanya satu thread
• OS modern:
– Banyak proses dan tiap proses terdiri dari banyak thread
– Misal: Windows, Solaris, Linux, Mach, dan OS/2


Manfaat Thread
• Pembentukan suatu thread jauh lebih cepat daripada pembentukan proses baru
– Penelitian menunjukkan pembentukan thread 10x lebih cepat daripada pembentukan proses
• Terminasi suatu thread jauh lebih cepat daripada terminasi proses
• Perpindahan eksekusi antar thread jauh lebih cepat
• Antar thread dapat berkomunikasi tanpa melibatkan kernel
– Sebagai efek dari penggunaan share memori dan file

Jenis Thread

• User-Level Thread (ULT)
– Semua manajemen thread dilakukan oleh program aplikasi
– Tidak ada code program untuk mengatur thread pada program kernel

• Kernel-Level Thread (KLT)
– kernel supported threads = lightweight process
– Semua manajemen thread dilakukan oleh kernel
– Tidak ada code program untuk mengatur thread pada program aplikasi


Model Multithreading

- Model One to One
Model one-to-one memetakan setiap thread pengguna ke dalam satu kernel thread. Hal ini membuat
model one-to-one lebih sinkron daripada model many-to-one dengan mengizinkan thread lain untuk
berjalan ketika suatu thread membuat pemblokingan terhadap sistem pemanggilan; hal ini juga
mengizinkan multiple thread untuk berjalan secara parallel dalam multiprosesor. Kelemahan model ini
adalah dalam pembuatan thread pengguna dibutuhkan pembuatan korespondensi thread pengguna.
Karena dalam proses pembuatan kernel thread dapat mempengaruhi kinerja dari aplikasi maka
kebanyakan dari implementasi model ini membatasi jumlah thread yang didukung oleh sistem. Model
one-to-one diimplementasikan oleh Windows NT dan OS/2.

- Model Many to One

Model many-to-one ini memetakan beberapa tingkatan pengguna thread hanya ke satu buah kernel
thread. Managemen proses thread dilakukan oleh (di ruang) pengguna, sehingga menjadi efisien, tetapi
apabila sebuah thread melakukan sebuah pemblokingan terhadap sistem pemanggilan, maka seluruh
proses akan berhenti (blocked). Kelemahan dari model ini adalah multihreads tidak dapat berjalan atau
bekerja secara paralel di dalam multiprosesor dikarenakan hanya satu thread saja yang bisa mengakses
kernel dalam suatu waktu.

- Model Many to Many

Beberapa tingkatan thread pengguna dapat menggunakan jumlah kernel thread yang lebih kecil atau
sama dengan jumlah thread pengguna. Jumlah dari kernel thread dapat dispesifikasikan untuk beberapa
aplikasi dan beberapa mesin (suatu aplikasi dapat dialokasikan lebih dari beberapa kernel thread dalam
multiprosesor daripada dalam uniprosesor) dimana model many-to-one mengizinkan pengembang untuk
membuat thread pengguna sebanyak mungkin, konkurensi tidak dapat tercapai karena hanya satu thread
yang dapat dijadualkan oleh kernel dalam satu waktu. Model one-to-one mempunyai konkurensi yang
lebih tinggi, tetapi pengembang harus hati-hati untuk tidak membuat terlalu banyak thread tanpa aplikasi
dan dalam kasus tertentu mungkin jumlah thread yang dapat dibuat dibatasi.

Thread Cancellation
Thread cancellation adalah tugas untuk memberhentikan thread sebelum ia menyelesaikan tugasnya. Sebagi contohnya jika dalam program java kita hendak mematikan JVM( Java Virtual Machine ) maka sebelum JVM-nya dimatikan maka seluruh thread yang berjalan dihentikan terlebuh dahulu. Thread yang akan diberhentikan biasa disebut target thread.
Pemberhentian target thread bisa terjadi melalui 2 cara yang berbeda :
Asynchronous cancellation : suatu thread seketika itu juga memberhentikan target thread.
Defered cancellation : target thread secara perodik memeriksa apakah dia harus berhenti, cara ini memperbolehkan targetthread untuk memberhentikan dirinya sendiri secara terurut.
Hal yang sulit dari pemberhentian thread ini adalah ketika terjadi situasi dimana sumber daya sudah dialokasikan untuk thread yang akan diberhentikan. Selain itu kesulitan lain adalah ketika thread yang diberhentikan sedang meng-update data yang ia bagi dengan thread lain. Hal ini akan menjadi masalah yang sulit apabila digunakan asynchronous cancellation . Sistem operasi akan mengambil kembali sumber daya dari thread yang diberhentikan tetapi seringkali sistem operasi tidak mengambil kembali semua sumber daya dari thread yang diberhentikan.
Alternatifnya adalah dengan menggunakan Deffered cancellation . Cara kerja dari deffered cancellation adalah dengan menggunakan 1 thread yang berfungsi sebagai pengindikasi bahwa target thread hendak diberhentikan. Tetapi pemberhentian hanya akan terjadi jika target thread memeriksa apakah ia harus berhenti atau tidak. Hal ini memperbolehkan thread untuk memeriksa apakah ia harus berhenti pada waktu dimana ia bisa diberhentikan secara aman yang aman. Pthread merujuk tersebut sebagai cancellation points .
Pada umumnya sistem operasi memperbolehkan proses atau thread untuk diberhentikan secara asynchronous . Tetapi Pthread API menyediakan deferred cancellation . Hal ini berarti sistem operasi yang mengimplementasikan Pthread API akan mengijinkan deferred cancellation .

Thread Pools

Pada web server yang multithreading ada dua masalah yang timbul:
Ukuran waktu yang diperlukan untuk menciptakan thread yang melayani permintaan yang diajukan pada kenyataannya thread dibuang seketika sesudah ia menyelesaikan tugasnya.
Pembuatan thread yang tidak terbatas jumlahnya dapat menurunkan performa dari sistem.
Solusinya adalah dengan penggunaan Thread Pools. Cara kerjanya adalah dengan membuat beberapa thread pada proses startup dan menempatkan mereka ke pools, dimana mereka duduk diam dan menunggu untuk bekerja. Jadi, ketika server menerima permintaan, ia akan membangunkan thread dari pool dan jika thread tersedia maka permintaan tersebut akan dilayani. Ketika thread sudah selesai mengerjakan tugasnya maka ia kembali ke pool dan menunggu pekerjaan lainnya. Bila tidak ada thread yang tersedia pada saat dibutuhkan maka server menunggu sampai ada satu thread yang bebas.
Keuntungan thread pool adalah:
Biasanya lebih cepat untuk melayani permintaan dengan thread yang ada dibandingkan menunggu thread baru dibuat.
Thread pool membatasi jumlah thread yang ada pada suatu waktu. Hal ini penting pada sistem yang tidak dapat mendukung banyak thread yang berjalan secara concurrent. Jumlah thread dalam pool dapat tergantung dari jumlah CPU dalam sistem, jumlah memori fisik, dan jumlah permintaan klien yang concurrent.

Thread Linux

Ketika pertama kali dikembangkan, Linux tidak didukung dengan threading di dalam kernelnya, tetapi dia mendukung proses-proses sebagai entitas yang dapat dijadwalkan melalui clone() system calls. Sekarang Linux mendukung penduplikasian proses menggunakan system call clone() dan fork(). Clone() mempunyai sifat mirip dengan fork(), kecuali dalam hal pembuatan copy dari proses yang dipanggil dimana ia membuat sebuah proses yang terpisah yang berbagi address space dengan proses yang dipanggil. Pembagian address space dari parent process memungkinkan cloned task bersifat mirip dengan thread yang terpisah. Pembagian address space ini dimungkinkan karena proses direpresentasikan di dalam Kernel Linux. Di dalam Kernel Linux setiap proses direpresentasikan sebagai sebuah struktur data yang unik. Jadi, daripada menciptakan yang baru maka struktur data yang baru mengandung pointer yang menunjuk ke tempat dimana data berada. Jadi ketika fork() dipanggil, proses yang baru akan tercipta beserta duplikasi dari segala isi di struktur data di parent process, namun ketika clone() dipanggil, ia tidak menduplikasi parent processnya tetapi menciptakan pointer ke struktur data pada parent process yang memungkinkan child process untuk berbagi memori dan sumber daya dari parent processnya. Project LinuxThread menggunakan system call ini untuk mensimulasi thread di user space. Sayangnya, pendekatan ini mempunyai beberapa kekurangan, khusunya di area signal handling, scheduling, dan interprocess synchronization primitive.
Untuk meningkatkan kemampuan Thread Linux, dukungan kernel dan penulisan ulang pustaka thread sangat diperlukan. Dua project yang saling bersaing menjawab tantangan ini. Sebuah tim yang terdiri dari pengembang dari IBM membuat NGPT (Next Generation POSIX Threads). Sementara pengembang dari Red Hat membuat NPTL (Native POSIX Thread Library).Sebenarnya Linux tidak membedakan antara proses dan thread. Dalam kenyataannya, Linux lebih menggunakan istilah task dibandingkan proses dan thread ketika merujuk kepada pengaturan alur pengontrolan di dalam program.

Thread Java

Suatu proses dikontrol oleh paling sedikit satu thread. Namun, sebagian besar proses yang ada sekarang biasanya dijalankan oleh beberapa buah thread. Multithreading adalah sebuah mekanisme di mana dalam suatu proses, ada beberapa thread yang mengerjakan tugasnya masing-masing pada waktu yang bersamaan. Contohnya, sebuah web browser harus menampilkan sebuah halaman yang memuat banyak gambar. Pada program yang single-threaded, hanya ada satu thread untuk mengatur suatu gambar, lalu jika gambar itu telah ditampilkan, barulah gambar lain bisa diproses. Dengan multithreading, proses bisa dilakukan lebih cepat jika ada thread yang menampilkan gambar pertama, lalu thread lain untuk menampilkan gambar kedua, dan seterusnya, di mana thread-thread tersebut berjalan secara paralel.
Saat sebuah program Java dieksekusi, yaitu saat main() dijalankan, ada sebuah thread utama yang bekerja. Java adalah bahasa pemrograman yang mendukung adanya pembentukan thread tambahan selain thread utama tersebut. Thread dalam Java diatur oleh Java Virtual Machine(JVM) sehingga sulit untuk menentukan apakah thread Java berada di user-level atau kernel-level.

New . Thread yang berada di status ini adalah objek dari kelas Thread yang baru dibuat, yaitu saat instansiasi objek dengan statement new. Saat thread berada di status new, belum ada sumber daya yang dialokasikan, sehingga thread belum bisa menjalankan perintah apapun.
Runnable . Agar thread bisa menjalankan tugasnya, method start() dari kelas Thread harus dipanggil. Ada dua hal yang terjadi saat pemanggilan method start(), yaitu alokasi memori untuk thread yang dibuat dan pemanggilan method run(). Saat method run() dipanggil, status thread berubah menjadi runnable, artinya thread tersebut sudah memenuhi syarat untuk dijalankan oleh JVM. Thread yang sedang berjalan juga berada di status runnable.
Blocked . Sebuah thread dikatakan berstatus blocked atau terhalang jika terjadi blocking statement, misalnya pemanggilan method sleep(). sleep() adalah suatu method yang menerima argumen bertipe integer dalam bentuk milisekon. Argumen tersebut menunjukkan seberapa lama thread akan “tidur”. Selain sleep(), dulunya dikenal method suspend(), tetapi sudah disarankan untuk tidak digunakan lagi karena mengakibatkan terjadinya deadlock. Di samping blocking statement, adanya interupsi M/K juga dapat menyebabkan thread menjadi blocked. Thread akan menjadi runnable kembali jika interval method sleep()-nya sudah berakhir, atau pemanggilan method resume() jika untuk menghalangi thread tadi digunakan method suspend() atau M/K sudah tersedia lagi.
Dead . Sebuah thread berada di status dead bila telah keluar dari method run(). Hal ini bisa terjadi karena thread tersebut memang telah menyelesaikan pekerjaannya di method run(), maupun karena adanya pembatalan thread. Status jelas dari sebuah thread tidak dapat diketahui, tetapi method isAlive() mengembalikan nilai boolean untuk mengetahui apakah thread tersebut dead atau tidak.
Pembentukan Thread
Ada dua cara untuk membuat thread di program Java, yaitu:
Extends kelas Thread
Implements interface Runnable.
Interface Runnable didefinisikan sebagai berikut:

public interface Runnable
{
public abstract void run();
}

Kelas Thread secara implisit juga meng- implements interface Runnable. Oleh karena itu, setiap kelas yang diturunkan dari kelas Thread juga harus mendefinisikan method run(). Berikut ini adalah contoh kelas yang menggunakan cara pertama untuk membuat thread, yaitu dengan meng- extends kelas Thread.

class CobaThread1 extends Thread
{
public void run()
{
for (int ii = 0; ii<4; ii++){
System.out.println("Ini CobaThread1");
Test.istirohat(11);
}
}
}

Konsep pewarisan dalam Java tidak mendukung multiple inheritance. Jika sebuah kelas sudah meng- extends suatu kelas lain, maka kelas tersebut tidak lagi bisa meng- extends kelas Thread. Oleh karena itu, cara kedua, yaitu meng- implements interface Runnable, lebih umum digunakan, karena kita bisa meng- implements dari banyak kelas sekaligus.

class CobaThread2 implements Runnable
{
public void run()
{
for(int ii = 0; ii<4; ii++){
System.out.println("Ini CobaThread2");
Test.istirohat(7);
}
}

public class Test
{
public static void main (String[] args)
{
Thread t1 = new CobaThread1();
Thread t2 = new Thread (new CobaThread2());
t1.start();
t2.start();

for (int ii = 0; ii<8; ii++){
System.out.println("Thread UTAMA");
istirohat(5);
}
}

public static void istirohat(int tunda)
{
try{
Thread.sleep(tunda*100);
} catch(InterruptedException e) {}
}
}

Pada bagian awal main(), terjadi instansiasi objek dari kelas CobaThread1 dan CobaThread2, yaitu t1 dan t2. Perbedaan cara penginstansian objek ini terletak pada perbedaan akses yang dimiliki oleh kelas-kelas tersebut. Supaya thread bisa bekerja, method start() dari kelas Thread harus dipanggil. Kelas CobaThread1 memiliki akses ke method-method yang ada di kelas Thread karena merupakan kelas yang diturunkan langsung dari kelas Thread. Namun, tidak demikian halnya dengan kelas CobaThread2. Oleh karena itu, kita harus tetap membuat objek dari kelas Thread yang menerima argumen objek CobaThread2 pada constructor-nya, barulah start() bisa diakses. Hal ini ditunjukkan dengan statement Thread t2 = new Thread (new CobaThread2()).
Jadi, ketika terjadi pemanggilan method start(), thread yang dibuat akan langsung mengerjakan baris-baris perintah yang ada di method run(). Jika run() dipanggil secara langsung tanpa melalui start(), perintah yang ada di dalam method run() tersebut akan tetap dikerjakan, hanya saja yang mengerjakannya bukanlah thread yang dibuat tadi, melainkan thread utama.
Share this article :

Posting Komentar

 
Copyright © 2011. BELAJAR PEMOGRAMAN - All Rights Reserved
Proudly powered by Fasilkom Universitas Esa Unggul