Yolanda Saputri - BAB4 [PDF]

  • 0 0 0
  • Suka dengan makalah ini dan mengunduhnya? Anda bisa menerbitkan file PDF Anda sendiri secara online secara gratis dalam beberapa menit saja! Sign Up
File loading please wait...
Citation preview

LABORATORIUM PEMBELAJARAN ILMU KOMPUTER FAKULTAS ILMU KOMPUTER UNIVERSITAS BRAWIJAYA NAMA NIM MATERI TANGGAL ASISTEN



: YOLANDA SAPUTRI : 195150201111064 : BAB IV : 06/11/2020 : FRANKLID GUNAWAN



BAB 4 SINKRONISASI 4.1.



Tujuan Praktikum



Bab ini bertujuan untuk mengenalkan konsep sinkronisasi dalam praktek sistem operasi Ubuntu. 4.2.



Capaian Praktikum 1. Mahasiswa mampu memahami konsep sinkronisasi 2. Mahasiswa mampu mempraktekkan konsep sinkronisasi



4.3.



Dasar Teori



4.3.1. Sinkronisasi Thread Thread library menyediakan tiga cara untuk mekanisme sinkronisasi, yaitu: • Mutex – Mutual Exclusion lock: digunakan untuk mem-blokir akses suatu variabel dari thread lain. Hal ini memastikan bahwa suatu variabel dalam suatu waktu hanya bisa dimodifikasi oleh suatu thread tertentu saja • Join – Membuat suatu thread hanya berjalan saat ada thread lain yang sudah selesai (terminate) • Condition Variable – menggunakan tipe data pthread_cond_t 4.3.2. Mutex Mutex digunakan untuk menghindari ketidakkonsistenan data karena sebuah variabel yang dimodifikasi oleh banyak thread dalam waktu yang bersamaan. Hal ini menyebabkan terjadinya apa yang disebut dengan race condition. Oleh karena itu, setiap ada variabel global yang bisa dimodifikasi oleh banyak thread, digunakan mutex untuk menjaga agar variabel global tersebut dimodifikasi oleh banyak threads dengan suatu urutan tertentu. Mutex berfungsi seperti lock and key, di mana jika suatu thread memodifikasi suatu variabel global, maka variabel tersebut hanya bisa dimodifikasi oleh thread lainnya setelah thread sebelumnya selesai memodifikasi variabel tersebut. Mutex ini hanya bisa digunakan oleh thread-



thread yang berasal dari satu proses yang sama, tidak seperti semaphore yang dapat digunakan untuk banyak thread dari proses yang berbeda-beda. •











Pthread_mutex_lock() – digunakan untuk mengunci suatu variabel. Jika mutex sudah di-lock oleh suatu thread, maka thread lain tidak bisa memanggil fungsi ini sampai mutex tersebut sudah di-unlock Pthread_mutex_unlock() – digunakan untuk membuka kunci suatu variabel. Pesan error akan muncul jika suatu thread memanggil fungsi ini padahal bukan thread tersebut yang mengunci mutex Pthread_mutex_trylock() – digunakan untuk mencoba mengunci suatu mutex dan akan mengembalikan pesan error jika terjadi keadaan busy. Hal ini berguna untuk mencegah terjadinya deadlock



4.3.3. Join Sebuah join digunakan jika diinginkan suatu keadaan sebuah thread baru akan berjalan setelah suatu thread lain selesai dijalankan. Sebuah thread dapat juga menjalankan suatu rutin yang menciptakan banyak thread baru di mana thread induk akan dijalankan lagi saat banyak thread baru tersebut sudah selesai dijalankan. • • •



Pthread_create() – membuat sebuah thread baru Pthread_join() – menunggu termination dari suatu thread lain Pthread_self() – mengembalikan nilai identifier dari thread yang sekarang dijalankan



4.3.4. Condition Variable Sebuah condition variable adalah variabel dari pthread_cond_t dan digunakan sebagai sebuah fungsi untuk menunggu dan melanjutkan proses eksekusi suatu thread. Menggunakan perintah ini dapat membuat sebuah thread berhenti dijalankan dan berjalan lagi berdasarkan suatu kondisi yang memenuhinya. • • • •



Creating/Destroying: pthread_cond_init; pthread_cond_t cond=PTHREAD_COND_INITILIZER; pthread_cond_destroy Waiting on condition: pthread_cond_wait; pthread_cond_timewait Waking thread based on condition: pthread_cond_signal; pthread_cond_broadcast



4.4.



Langkah Praktikum



Praktikum ini dilakukan dengan terlebih dahulu terhubung dengan layanan aws educate dengan cara mengaktifkan instance dari halaman instance summary. Pilih action dan Start untuk mengaktifkan instance. Lakukan koneksi SSH dengan cara yang sama seperti pada Bab 1. 1. Lakukan percobaan terhadap tiap kode program pada masingmasing sub bab berikut. 2. Lakukan kompilasi kode program dengan menggunakan perintah gcc -pthread main.c -o main



3. Jalankan hasil kompilasi menggunakan perintah ./main 4. Capture/ Sanpshot output-nya dan simpan sebagai laporan. 5. Amati output tiap percobaan dan jawab pertanyaan pada masingmasing percobaan. 4.4.1. Mutex main.c 1 #include 2 #include 3 #include 4 5 pthread_mutex_t mutex1 = 6 PTHREAD_MUTEX_INITIALIZER; 7 int counter = 0; 8 9 void *increase() { 10 pthread_mutex_lock( &mutex1 ); 11 int i; 12 13 for(i = 0; i < 99999; i++) { 14 counter++; 15 printf("Counter value: %d\n",counter); 16 } 17 18 pthread_mutex_unlock( &mutex1 ); 19 } 20 21 void *decrease() { 22 pthread_mutex_lock( &mutex1 ); 23 int i; 24 25 for(i = 0; i < 99999; i++) { 26 counter--;



27



printf("Counter value: %d\n",counter); 28 } 29 30 pthread_mutex_unlock( &mutex1 ); 31 } 32 33 int main() { 34 int rc1, rc2; 35 pthread_t thread1, thread2; 36 37 /* Create independent threads each of which will execute increase */ 38 if( (rc1=pthread_create( &thread1, NULL, &increase, NULL)) ) { 39 printf("Thread creation failed: %d\n", rc1); 40 } 41 42 /* Create independent threads each of which will execute decrease */ 43 if( (rc2=pthread_create( &thread2, NULL, &decrease, NULL)) ) { 44 printf("Thread creation failed: %d\n", rc2); 45 } 46 47 /* Wait till threads are complete before main continues. Unless we */ 48 /* wait we run the risk of executing an exit which will terminate */ 49 /* the process and all threads before the threads have completed. */ 50 pthread_join( thread1, NULL); 51 pthread_join( thread2, NULL); 52 53 exit(EXIT_SUCCESS); 54 }



Berdasarkan output dari program tersebut, jawablah pertanyaan berikut: 1. Jalankan program tersebut sebanyak 10 kali. Apakah semua output yang dihasilkan sama? Tips: Anda dapat menyimpan output program ke dalam file text dengan cara menambahkan > namafile.txt di akhir perintah, misal: ./main > output1.txt



Jawab: Iya. Dari output 1 hingga output 10, semua output yang dihasilkan sama, tidak ada perbedaan. Bisa dicek dengan perintah ”cmp output1.txt output2.txt” dan seterusnya seperti pada Gambar 4, dari hasil Gambar 4 membuktikan jika tidak ada perbedaan output 1 sampai dengan 10.



Gambar 1 Screenshot hasil menulis kode pada nano



Gambar 2 Screenshot hasil kompilasi kode program



Gambar 3 Screenshot hasil membuat 10 program



Gambar 4 Screenshot hasil dari menjalankan program



2. Hapus kode program pada baris 9, 15, 19, dan 25 yang berisi perintah pthread_mutex_lock dan pthread_mutex_unlock. Kemudian jalankan program tersebut sebanyak 10 kali. Apakah semua output yang dihasilkan sama? Jawab:



Tidak, output yang dihasilkan tidak sama seperti pada Gambar 7 dan 8 diketahui bahwa output1.txt dan output2.txt memiliki perbedaan pada line 17025. Hal ini disebabkan oleh perintah pthread_mutex_lock dan pthread_mutex_unlock dihapus.



Gambar 5 Screenshot hasil menghapus kode baris 9,15,19 dan 25



Gambar 6 Screenshot hasil kompilasi dan membuat 10 program



Gambar 7 Screenshot hasil menjalankan program



Gambar 8 Screenshot hasil output yang berbeda



3. Berdasarkan hasil pengamatan anda, simpulkan fungsi dari pthread_mutex_lock dan pthread_mutex_unlock dalam program tersebut! Jawab: Berdasarkan hasil pengamatan saya, menyimpulkan fungsi dari pthread_mutex_lock dan pthread_mutex_unlock adalah : Jika pthread_mutex_lock sendiri digunakan untuk mengunci suatu mutex thread agar tidak dapat diakses. Namun jika pthread_mutex_unlock berfungsi untuk membuka kunci atau melepas status lock dari suatu mutex thread yang dikunci. Sehingga saat kedua perintah tersebut dihapus maka suatu mutex thread yang ada tidak dapat dikunci. 4.4.2. Join



main.c 1 #include 2 #include 3 4 pthread_mutex_t mutex1 = 5 PTHREAD_MUTEX_INITIALIZER; 6 int counter = 0; 7 8 void *thread_function(void *dummyPtr) { 9 pthread_mutex_lock( &mutex1 ); 10 counter++; 11 pthread_mutex_unlock( &mutex1 ); 12 } 13 14 int main() { 15 pthread_t thread_id[100]; 16 int i, j; 17 18 for(i = 1; i 6 ) { 33 // Condition of if statement has been met. 34 // Signal to free waiting thread by freeing the mutex. 35 // Note: functionCount1() is now permitted to modify "count". 36 pthread_cond_signal( &condition_var ); 37 } else { 38 count++; 39 printf("Counter value functionCount2: %d\n",count); 40 } 41 pthread_mutex_unlock( &count_mutex ); 42 43 if(count >= 10) 44 return(NULL); 45 } 46 } 47 48 int main() { 49 pthread_t thread1, thread2; 50 pthread_create( &thread1, NULL, &functionCount1, NULL); 51 pthread_create( &thread2, NULL, &functionCount2, NULL); 52 pthread_join( thread1, NULL); 53 pthread_join( thread2, NULL); 54 printf("Final count: %d\n",count);



55 56 }



exit(EXIT_SUCCESS);



Berdasarkan output dari program tersebut, jawablah pertanyaan berikut: 1. Jalankan program tersebut. Apakah semua output yang dihasilkan sama? Jawab: Iya. Dari output 1 hingga output 10, semua output yang dihasilkan sama, tidak ada perbedaan. Bisa dicek dengan perintah ”cmp output1.txt output2.txt” dan seterusnya seperti pada Gambar 17, dari hasil Gambar 17 membuktikan jika tidak ada perbedaan output 1 sampai dengan 10.



Gambar 15 Screenshot hasil menulis kode pada nano



Gambar 16 Screenshot hasil kompilasi dan membuat 10 program



Gambar 17 Screenshot hasil dari menjalankan program



2. Hapus kode program pada baris 17 yang berisi perintah pthread_cond_wait. Kemudian jalankan program tersebut. Apakah semua output yang dihasilkan sama dengan output pada soal 1? Jawab: Iya. Dari output 1 hingga output 10, semua output yang dihasilkan sama, tidak ada perbedaan sama dengan output yang dihasilkan pada soal nomor 1. Bisa dicek dengan perintah ”cmp output1.txt output2.txt” dan seterusnya seperti pada Gambar 20, dari hasil Gambar 20 membuktikan jika tidak ada perbedaan output 1 sampai dengan 10.



Gambar 18 Screenshot hasil menghapus kode baris 17



Gambar 19 Screenshot hasil kompilasi dan membuat 10 program



Gambar 20 Screenshot hasil dari menjalankan program



3. Kembalikan (undo) kode program seperti saat anda mengerjakan soal 1, kemudian hapus kode program pada baris 37 yang berisi perintah pthread_cond_signal. Kemudian jalankan program tersebut. Apakah semua output yang dihasilkan sama dengan output pada soal 1? Jawab: Tidak sama, saat baris ke 37 yang berisi perintah pthread_cond_signal ini dihapus maka program tidak dapat berjalan.



Gambar 21 Screenshot hasil menjalankan program



4. Berdasarkan hasil pengamatan anda setelah soal 1 s.d. 3, simpulkan fungsi dari pthread_cond_wait dan pthread_cond_signal dalam program tersebut! Jawab: Berdasarkan hasil pengamatan saya, menyimpulkan fungsi dari pthread_cond_wait dan pthread_cond_signal adalah : Jika pthread_cond_wait sendiri berfungsi untuk menunggu sinyal dari pthread_cond_signal agar dapat mengerjakan syntax yang disediakan dan untuk memblokir/menghentikan sementara jalannya eksekusi suatu thread. Namun jika pthread_cond_signal berfungsi untuk melanjutkan kembali eksekusi thread yang diblokir tadi setelah suatu kondisi berhasil dipenuhi.



LABORATORIUM PEMBELAJARAN ILMU KOMPUTER FAKULTAS ILMU KOMPUTER UNIVERSITAS BRAWIJAYA NAMA NIM TUGAS TANGGAL ASISTEN



: YOLANDA SAPUTRI : 195150201111064 : BAB IV : 06/11/2020 : FRANKLID GUNAWAN



4.5.1. Tugas 1 Jalankan kode program berikut! soal.c 1 #include 2 #include 3 #include 4 #include 5 #include 6 7 int counter = 0; 8 pthread_t tid[4]; 9 10 void* doSomeThing(void *arg) { 11 printf("\n Thread %d started, please wait...\n", counter); 12 counter++; 13 unsigned long i = 0; 14 15 for(i = 0; i < (0xFFFFFFFF); i++); 16 17 printf("\n Thread %d finished\n", counter); 18 19 return NULL; 20 } 21 22 int main(void) { 23 int i; 24 25 for(i = 0; i < 4; i++) 26 pthread_create(&(tid[i]), NULL, &doSomeThing, NULL); 27 28 for(i = 0; i < 4; i++) 29 pthread_join(tid[i], NULL); 30 return 0; 31 }



Bila anda berhasil menjalankan kode program tersebut, maka anda akan mendapati output seperti pada gambar di bawah ini.



Jawablah pertanyaan berikut ini: 1. Mengapa perintah printf pada bari 11 pada masing-masing thread menampilkan nilai counter yang berbeda? Jawab: Perintah printf pada baris 11 pada masing-masing thread menampilkan nilai counter yang berbeda karena printf pada baris 11 terdapat perintah counter++ yang mengakibatkan nilai counternya akan selalu bertambah setiap kali method doSomething dijalankan. 2. Mengapa pada semua thread perintah printf pada baris 17 menampilkan nilai Thread 4 finished? Jawab: Pada semua thread perintah printf pada baris 17 menampilkan nilai Thread 4 finished karena pada segmen kode baris 17 tidak digunakan metode sinkronisasi, sehingga variabel yang terdapat di segmen kode tersebut dapat diakses oleh lebih dari satu thread. Jadi jika thread 0 mengakses variabel tersebut, maka thread lainnya yaitu thread 4 dapat mengaksesnya juga sehingga nilai keempat thread ini akan mengeluarkan counter yang sama. 3. Apa fungsi for pada baris 14? Berapa kali looping yang dilakukan oleh perintah for tersebut? Jawab:



Fungsi for pada baris 14 ini berperan sebagai salah satu penyebab keempat thread memiliki nilai counter yang sama. Dan for ini juga berfungsi untuk menjaga thread yang terbentuk dalam kondisi running sambil memastikan thread yang lain terbentuk terlebih dahulu sebelum looping selesai dijalankan. Looping yang telah dilakukan oleh perintah for tersebut sebenarnya sebanyak 4294967295 karena 0XFFFFFFFF adalah representasi heksadesimal dari nilai 4294967295, namun karena hanya terdapat 4 kali pencetakan kalimat thread 4 finished dan sisanya adalah NULL. 4.5.2. Tugas 2 Modifikasilah kode program pada Tugas 1 dengan menambahkan pthread_mutex_lock dan pthread_mutex_unlock. Sehingga menghasilkan output seperti pada gambar di bawah ini.



Jawablah pertanyaan berikut ini: 1. Jelaskan kode program hasil modifikasi anda! Jelaskan pula alasan penempatan pthread_mutex_lock dan pthread_mutex_unlock pada kode program hasil modifikasi anda! Jawab:



Gambar 22 Screenshot hasil modifikasi kode program



Modifikasi yang saya lakukan pada kode program diatas adalah dengan menmbahkan “pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;” pada baris ke-8. Menambahkan kode program “pthread_mutex_lock(&mutex1);” pada baris ke-10. Lalu menambahkan kode program “ptread_mutex_unlock(&mutex1);” pada baris ke-18. Alasan penempatan kode program pthread_mutex_lock di awal method doSomething() dan kode program pthread_mutex_unlock di akhir method doSomething() ialah agar sebuah thread dapat menyelesaikan eksekusinya hingga akhir sebelum thread lain dapat mengakses method tersebut. 2. Dari segi waktu eksekusi, bagaimanakah perbandingan keceptan eksekusi kode program pada Tugas 1 dengan kode program hasil modifikasi anda pada Tugas 2? Jawab:



Gambar 23 Screenshot segi waktu eksekusi Tugas1 dan Tugas2



Dari segi waktu eksekusi, perbandingan kecepatan eksekusi kode program pada tugas 1 dengan kode program hasil modifikasi pada tugas 2 adalah dapat diketahui jika pada program di tugas 1 memiliki waktu eksekusi yang lebih cepat karena program 2 terdapat perintah pthread_mutex_lock dan pthread_mutex_unlock, jadi suatu thread terpaksa menunggu thread lain menyelesaikan eksekusinya, barulah giliran thread selanjutnya. 4.5.3. Tugas 3 Modifikasilah kode program pada Tugas 1 pada baris 24 s.d. 28 menjadi seperti berikut. soal.c ... ... 24 for(i = 0; i < 4; i++) { 25 pthread_create(&(tid[i]), NULL, &doSomeThing, NULL); 26 pthread_join(tid[i], NULL); 27 } ... ...



Jawablah pertanyaan berikut ini: 1. Tampilkan output kode program tersebut! Jelaskan dampak dari modifikasi tersebut! Jawab:



Gambar 24 Screenshot output kode program



Output kode program tersebut sama dengan output kedua program pada tugas 2 karena thread dibuat secara berurutan, maksudnya adalah thread lain akan menunggu thread yang sedang dieksekusi hingga selesai terlebih dahulu. Jadi, thread kedua akan dibuat setelah thread pertama, thread ketiga setelah thread kedua, dan seterusnya. Bedanya pada mutex, thread dibuat sekaligus tapi dieksekusi secara bergantian sedangkan join dibuat setelah suatu thread selesai dieksekusi. 2. Dari segi wakt eksekusi, bagaimanakah perbandingan kecepatan eksekusi kode program pada Tugas 1, kode program hasil modifikasi anda pada Tugas 2, dan kode program pada Tugas 3? Jelaskan alasannya! Jawab:



Gambar 25 Screenshot segi waktu eksekusi Tugas1, Tugas2 dan Tugas3



Dari segi waktu eksekusi, perbandingan kecepatan eksekusi kode program pada tugas 1 dengan kode program hasil modifikasi pada tugas 2 adalah dapat diketahui jika pada program di tugas 1 memiliki waktu eksekusi yang lebih cepat karena waktu eksekusi akan lebih cepat pada program yang sebelum dimodifikasi. Hal ini dikarenakan jika memakai join harus menunggu thread yang yang berhubungan. Sehingga keadaan sebuah thread baru akan berjalan setelah suatu thread lain selesai dijalankan.



LABORATORIUM PEMBELAJARAN ILMU KOMPUTER FAKULTAS ILMU KOMPUTER UNIVERSITAS BRAWIJAYA NAMA NIM KESIMPULAN TANGGAL ASISTEN



: YOLANDA SAPUTRI : 195150201111064 : BAB IV : 06/11/2020 : FRANKLID GUNAWAN



Jelaskan kesimpulan dari hasil percobaan pada Bab 4 ini. Sinkronisasi berarti kurang lebih seperti dalam suatu proses pengendalian akses dari sumber daya (shared resource) oleh banyak thread sehingga hanya terdapat satu thread yang bisa mengakses suatu sumber daya pada satu waktu. Sinkronisasi thread memiliki thread library yang menyediakan tiga cara mekanisme sinkronisasi yaitu : 1. Mutex – Mutual Exclusion lock Mutex digunakan untuk mem-blokir akses suatu variabel dari thread lain. Hal ini memastikan bahwa suatu variabel dalam suatu waktu hanya bisa dimodifikasi oleh suatu thread tertentu saja. Serta digunakan untuk menghindari ketidakkonsistenan data karena sebuah variabel yang dimodifikasi oleh banyak thread dalam waktu yang bersamaan. 2. Join Membuat suatu thread hanya berjalan saat ada thread lain yang sudah selesai (terminate). 3. Condition Variable Sebuah condition variable adalah variabel dari pthread_cond_t dan digunakan sebagai sebuah fungsi untuk menunggu dan melanjutkan proses eksekusi suatu thread. Menggunakan perintah ini dapat membuat sebuah thread berhenti dijalankan dan berjalan lagi berdasarkan suatu kondisi yang memenuhinya. Menggunakan tipe data pthread_cond_t.