Anda di halaman 1dari 11

BAB IV

THREADS

Pendahuluan
Salah satu tujuan penting dari pembentukan thread adalah untuk memungkinkan
eksekusi secara konkuren dan paralel. Dari sebuah program atau aplikasi, bisa jadi
terdapat banyak instruksi yang dapat dilakukan secara paralel tanpa mempengaruhi
instruksi yang lain.
Langkah awal sebelum penggunaan thread adalah memastikan apakah sebuah
program benar-benar membutuhkannya. Sebagai contoh, sebuah program
dirancang untuk membaca dan menampilkan berkas. Maka untuk program ini, bisa
dibagi dalam dua atau lebih thread yang berbeda, satu thread untuk membaca
berkas, satu thread lain untuk memperbarui tampilan dan mungkin satu thread
lainnya untuk memantau input pengguna melalui keyboard.
Dan perlu diperhatikan bahwa akan ada kasus ketika sebuah thread tergantung satu
dengan yang lainnya seperti pada kasus di atas. Jika aplikasi tersebut berupa
pengolah kata dimana ketika tombol karakter ditekan maka harus segera
diinformasikan ke thread lain untuk memperbaharui tampilan atau membuka menu
lain atau menjalankan tindakan yang sesuai. Hal ini akan mempengaruhi hasil akhir
dari proses secara keseluruhan.
Tujuan dari pelaksanaan praktikum ini adalah untuk memberikan pemahaman
praktis bagaimana proses dengan beberapa threads dijalankan pada sistem operasi
berbasis linux. Serta juga menunjukkan bahwa pembentukan thread bisa menjadi
penyebab munculnya inkonsistensi hasil akhir dari sebuah proses jika thread tidak
dijalankan dengan benar.

Teori Pendukung

Thread dapat dikatakan merupakan bagian terkecil dari sebuah proses yang bisa
dieksekusi atau dijalankan. Satu proses bisa memiliki beberapa thread yang dapat
dieksekusi secara asinkron. Eksekusi asinkron ini membawa kemampuan setiap
thread menangani pekerjaan atau layanan tertentu secara independen yang jika
digabungkan kembali akan setara dengan hasil eksekusi seluruh proses dengan
lengkap.
Thread pada sistem operasi modern telah menjadi bagian penting. Misalkan sebuah
proses, berfungsi untuk menerima masukan secara real time dan sesuai dengan
masing-masing masukan, proses tersebut harus menghasilkan luaran tertentu. Jika
prosesnya tidak dibuat menjadi beberapa thread berbeda (multi-thread), maka
instruksi dalam proses akan dieksekusi secara berurutan atau dalam terminologi
sistem operasi sering disebut eksekusi sinkron.

1
Keterbatasan dalam hal ini adalah proses tidak dapat menerima masukan sampai
pemrosesan masukan sebelumnya telah selesai. Dan jika pemrosesan masukan
sebelumnya membutuhkan waktu yang lama, maka masukan selanjutnya akan terus
ditahan. Solusi atas permasalahan ini adalah memecah proses menjadi beberapa
thread yang berbeda, agar proses tersebut dapat dijalankan secara asinkron.
Berikut adalah beberapa perbedaan utama antara proses dan thread:
Proses tidak berbagi informasi pengalamatan dengan proses lain, sementara
thread akan membagi informasi pengalamatannya dengan thread lain yang
dieksekusi di bawah proses yang sama.
Proses dieksekusi secara independen dan berbeda antara satu proses dengan
proses yang lain. Sinkronisasi antara proses dikelola oleh kernel. Sementara
disisi lain, sinkronisasi thread diatur oleh proses yang memiliki thread tersebut.
Proses context-switching antar thread jauh lebih cepat dibandingkan dengan
proses.
Interaksi antara dua proses hanya dapat dilakukan melalui komunikasi antar
proses standar, sedangkan thread berkomunikasi dengan mudah karena berbagi
sebagian besar sumber daya seperti memori, segmen teks, dll.
Namun, dibalik kemudahan dan kecepatan yang bisa didapatkan dengan
mengimplementasikan thread, terdapat banyak masalah yang mungkin muncul.
Diantaranya adalah kemungkinan terjadinya overwrite data dan isi memori secara
keseluruhan jika sebuah thread mengeksekusi sebuah aplikasi lain atau aplikasi
baru yang berbeda.
Masalah lain yang mungkin timbul adalah masalah konsistensi data. Karena thread
berbagi hampir semua komponen (kecuali stack) dan eksekusinya dapat dihentikan
setiap saat (preemptive) pada tahap apa pun oleh thread yang lain, maka ada
kemungkinan variabel atau struktur data global yang ada menjadi tidak konsisten.
Hal ini dapat menyebabkan masalah saat thread yang berbeda mengeksekusi fungsi
yang sama dan menggunakan variabel atau struktur data yang sama.

Gambar 1. Inkonsistensi Data karena Penggunaan Threads

2
Materi dan Langkah Praktikum

1. Aktifkan sistem operasi linux yang telah diinstall sebelumnya. Login ke sistem
dan kemudian buka sebuah console shell atau aplikasi terminal jika
menggunakan mode GUI.
2. Gunakan aplikasi pengolah teks yang ada pada sistem operasi linux seperti nano,
pico ataupun vi dan vim.
3. Tuliskan kode program berikut ini pada sebuah berkas baru.
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>

void * thread1()
{
while(1){
printf("Hello!!\n");
}
}

void * thread2()
{
while(1){
printf("How are you?\n");
}
}

int main()
{
int status;
pthread_t tid1,tid2;

pthread_create(&tid1,NULL,thread1,NULL);
pthread_create(&tid2,NULL,thread2,NULL);
pthread_join(tid1,NULL);

3
pthread_join(tid2,NULL);
return 0;
}

[ss source code]

4. Simpan berkas baru tersebut dengan nama threadsatu.c

[gambar/bukti file pada folder secara GUI (window) atau hasil $ ls]

5. Kompilasi kode program threadsatu.c melalui terminal dengan menuliskan


perintah [admin@host]$ gcc threadsatu.c lpthread o threadsatu

[ss perintah pada terminal]

6. Jalankan program baru tersebut diatas. Tunjukkan tampilan yang ada pada
terminal serta berikan penjelasan singkat dari tampilan tersebut.
[ss output program dan penjelasan]

7. Kembali tuliskan kode program berikut ini pada sebuah berkas baru.
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>

pthread_t tid[2];

void* doSomeThing(void *arg)


{
unsigned long i = 0;
pthread_t id = pthread_self();
if(pthread_equal(id,tid[0]))
{
printf("\n First thread processing\n");

4
}
else
{
printf("\n Second thread processing\n");
}
for(i=0; i<(0xFFFFFFFF);i++);
return NULL;
}

int main(void)
{
int i = 0;
int err;

while(i < 2)
{
err = pthread_create(&(tid[i]), NULL, &doSomeThing, NULL);
if (err != 0)
printf("\ncan't create thread :[%s]", strerror(err));
else
printf("\n Thread created successfully\n");
i++;
}
sleep(5);
return 0;
}

[ss source code]

8. Simpan berkas kedua ini dengan nama threaddua.c

[gambar/bukti file pada folder secara GUI (window) atau hasil $ ls]

5
9. Kompilasi kode program threaddua.c melalui terminal dengan menuliskan
perintah [admin@host]$ gcc threaddua.c lpthread o threaddua
[ss perintah pada terminal]

10. Jalankan program baru tersebut diatas. Tunjukkan tampilan yang ada pada
terminal serta berikan penjelasan singkat dari tampilan tersebut.
[ss output program dan penjelasan]

11. Buka aplikasi terminal yang lain, dan jalankan kedua thread tersebut.
[ss output program pada terminal pertama dan kedua]

12. Temukan identitas proses (dan mungkin juga thread) yang terkait dengan
perintah eksekusi kedua thread tersebut!
[ss PID yang terkait]

13. Apakah yang bisa dijelaskan dari kedua contoh thread diatas? Apa yang menjadi
masalah utama dalam hal ini?
[penjelasan nomor 11 dan 12]

14. Berikut ini adalah sebuah kode program yang dijalankan secara sekuensial.
Dibentuk menjadi satu proses dengan single thread.

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

static int num_accts = 1024; // number of bank accounts


static int num_trans = 10000; // number of transactions
static int think_time = 50; // amount of "thinking time"

6
struct acct_t {
int bal;
};

/*
* Pointer to accounts
*/
struct acct_t *accts;

/*
* Method to perform a number of transactions.
* Parameter "dummy" is not used.
*/
void *transact(void *dummy)
{
int i;
for (i = 0; i < num_trans; i++) {
// pick two random accounts
int acct_id_from = rand() % num_accts;
int acct_id_to = rand() % num_accts;
// pick a random amount
int amt = rand() % 100;

// try to transfer the money


if (accts[acct_id_from].bal > amt) {
accts[acct_id_from].bal -= amt;
accts[acct_id_to].bal += amt;

// "thinking time"... don't modify this code!!


amt *= think_time; while (amt--) ;
}
}

7
}

int main(int argc, char **argv)


{
// make sure the number of arguments is odd (including the
program name)
if (!(argc == 1 || argc == 3 || argc == 5 || argc == 7)) {
fprintf(stderr, "usage: %s [-a <accts>] [-i <transactions>]
[-t <think-time>]\n", argv[0]);
exit(-1);
}
// look at each runtime argument and see which value it's
attempting to set
int i;
for (i = 1; i < argc; i++) {
if (!strcmp(argv[i], "-a")) {
num_accts = atoi(argv[i+1]);
i++;
} else if (!strcmp(argv[i], "-i")) {
num_trans = atoi(argv[i+1]);
i++;
} else if (!strcmp(argv[i], "-t")) {
think_time = atoi(argv[i+1]);
i++;
} else {
fprintf(stderr, "usage: %s [-a <accts>] [-i <transactions>]
[-t <think-time>]\n", argv[0]);
exit(-1);
}
}

// display the parameters that will be used for this test run
fprintf(stderr, "%s: -a %d -i %d -t %d\n", argv[0], num_accts,
num_trans, think_time);

8
// initialize the random number generator
srand(1);

// create the bank accounts


accts = (struct acct_t *)malloc(num_accts * sizeof(struct
acct_t));

// initialize the bank accounts' values and keep track of the


total sum in all accounts
int original_sum = 0;
for (i = 0; i < num_accts; i++) {
accts[i].bal = rand() % 1000;
original_sum += accts[i].bal;
}

// call the transact function to do the transfers


transact(NULL);

// find the total sum of all accounts after the transfers are
done
int sum = 0;
for (i = 0; i < num_accts; i++) {
sum += accts[i].bal;
}

// if the sum is not equal to the original sum, then we had a


race condition!!
if (sum != original_sum) {
fprintf(stderr, "ERROR! original_sum = %d, sum = %d\n",
original_sum, sum);
}
else {
fprintf(stderr, "Values are still consistent\n");

9
}
return 0;
}

[ss source code]

15. Kompilasi kode program tersebut dan simpan dengan nama berkas
singlethread.

[ss perintah kompilasi]

16. Jalankan, tunjukkan dan berikan penjelasan singkat terkait eksekusi program
tersebut.
[ss output program dan penjelasan]

10
17. Buat tulisan ilmiah yang berisi penjelasan tentang kode program singlethread
yang telah dimodifikasi dengan aturan sebagai berikut:
a. Modifikasi kode tersebut menjadi beberapa thread yang berbeda dan
simpan dengan nama berkas threadtiga.

b. Deskripsi tentang hasil eksekusi program threadtiga beserta


penjelasannya.
c. Terdiri dari minimal 1000 kata diluar judul, sub judul, kode program dan
referensi.

11

Anda mungkin juga menyukai