Review Konsep Thread - Bebas - vLSM
Review Konsep Thread - Bebas - vLSM
Review Konsep Thread - Bebas - vLSM
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
<strong>Review</strong> <strong>Konsep</strong> <strong>Thread</strong><br />
Anggota Kelompok<br />
1. Genta Moerita (A 0606104265)<br />
2. Yuan Hanif Syaniardi (B 0606031603)<br />
3. Yunus Kuntawi Aji (B 0606031616)<br />
Komentar Umum<br />
Secara umum menurut kami bab 11 mengenai konsep thread ini sudah cukup jelas dalam<br />
menggambarkan multithreading. Gambar yang tersedia juga sudah cukup memberikan<br />
pemahaman terhadap konsep model-model multithreading. Beberapa hal yang perlu<br />
ditambahkan adalah kerugian dari multithreading dan contoh thread pada Sistem Operasi lain.<br />
Hubungan dengan bab sebelumnya/selanjutnya<br />
Bab ini menerangkan tentang multithreading dimana dalam suatu waktu bisa terjadi lebih dari<br />
satu proses yang konsepnya telah dijelaskan pada bab sebelumnya, yaitu bab 10 tentang<br />
<strong>Konsep</strong> Proses.<br />
Bab selanjutnya membahas tentang penggunaan thread pada java, thread bisa memiliki status<br />
new, runnable, block, dead.<br />
Komentar kelengkapan per bagian<br />
11.1 Bagian ini sudah lengkap karena sudah menerangkan definisi dari multithreading dan<br />
alasan membuat thread<br />
11.2 Bagian ini masih kurang lengkap, sebaiknya ditambah dengan kekurangan multithreading<br />
11.3 Ilustrasi gambar pada bab ini sudah cukup menjelaskan secara lengkap tentang model<br />
multithreading<br />
11.4 Bab ini perlu ditambah lagi tentang penjelasan pustaka thread<br />
11.5 Pada penjelasan cara pemberhentian thread perlu sedikit pengubahan redaksi kalimat<br />
11.6 Di dalam bab ini perlu ditambahkan definisi mengenai <strong>Thread</strong> Pools<br />
11.7 - Terdapat kesalahan penulisan pada paragraf dua baris pertama pada kata multithreading<br />
- Untuk memperjelas pemahaman mungkin perlu ditambahkan ilustrasi gambar<br />
11.8 Perlu diberi contoh thread dari sistem operasi yang lain untuk memperkaya pemahaman<br />
dan pengetahuan.<br />
11.9 Di dalam kesimpulan perlu ditambahkan rangkuman tentang pustaka thread<br />
Usulan kelengkapan<br />
11.1 Perlu ada sedikit pengubahan redaksi<br />
11.2 Bagian ini sebaiknya ditambah dengan kekurangan multithreading
11.3 - Perlu ditambahkan contoh pada model many-to-many<br />
- Perlu penjelasan lebih mengenai kelebihan dan kekurangan tiap model<br />
11.4 Perlu diberikan definisi atau penjelasan lebih tentang pustaka thread<br />
11.5 Perlu dilakukan perubahan redaksi kalimat dalam cara pemberhentian thread<br />
11.6 Perlu ditambahkan definisi mengenai <strong>Thread</strong> Pools<br />
11.7 Tambahkan ilustrasi gambar<br />
11.8 Perlu diberi contoh thread dari sistem operasi yang lain untuk memperkaya pemahaman<br />
dan pengetahuan.<br />
11.9 Di dalam kesimpulan perlu ditambahkan rangkuman tentang pustaka thread
Bab 11. <strong>Konsep</strong> <strong>Thread</strong><br />
11.1. Pendahuluan<br />
Pada bab sebelumnya kita telah mempelajari tentang proses, namun seiring berjalannya waktu<br />
dan tuntutan teknologi ternyata ditemukan kelemahan yang sebenarnya bisa diminimalisir pada<br />
proses. Untuk itulah diciptakan thread yang merupakan cara dari komputer untuk menjalankan<br />
dua atau lebih task dalam waktu bersamaan, sedangkan multithreading adalah cara komputer<br />
untuk membagi-bagi pekerjaan yang dikerjakan sebagian-sebagian dengan cepat sehingga<br />
menimbulkan efek seperti menjalankan beberapa task secara bersamaan walaupun otaknya<br />
hanya satu. Di sini kita akan belajar mengapa harus ada thread, perbedaan thread dengan<br />
proses, keuntungan dan kerugian pengimplementasian thread, model-model multithreading,<br />
pengimplementasian pustaka thread, pembatalan thread, thread pools, penjadwalan thread dan<br />
thread di Linux.<br />
11.2. Keuntungan dan Kerugian Multi<strong>Thread</strong>ing<br />
Multiprocessing merupakan penggunaan dua atau lebih CPU dalam sebuah sistem komputer.<br />
Multitasking merupakan metode untuk menjalankan lebih dari satu proses dimana terjadi<br />
pembagian sumberdaya seperti CPU. Multithreading adalah cara pengeksekusian yang<br />
mengizinkan beberapa thread terjadi dalam sebuah proses, saling berbagi sumber daya tetapi<br />
dapat dijalankan secara independen.<br />
Keuntungan dari sistem yang menerapkan multithreading dapat kita kategorikan menjadi 4<br />
bagian:<br />
a. Responsif. Aplikasi interaktif menjadi tetap responsif meskipun sebagian dari program sedang<br />
diblok atau melakukan operasi lain yang panjang. Umpamanya, sebuah thread dari web browser<br />
dapat melayani permintaan pengguna sementara thread yang lain berusaha menampilkan<br />
gambar.<br />
b. Berbagi sumber daya. Beberapa thread yang melakukan proses yang sama akan berbagi<br />
sumber daya. Keuntungannya adalah mengizinkan sebuah aplikasi untuk mempunyai beberapa<br />
thread yang berbeda dalam lokasi memori yang sama.<br />
c. Ekonomis. Pembuatan sebuah proses memerlukan pengalokasian memori dan sumber daya.<br />
Alternatifnya adalah dengan menggunakan thread, karena thread membagi memori dan sumber<br />
daya yang dimilikinya sehingga lebih ekonomis untuk membuat thread dan context switching<br />
thread. Akan susah mengukur perbedaan waktu antara thread dan switch, tetapi secara umum<br />
pembuatan dan pengaturan proses akan memakan waktu lebih lama dibandingkan dengan<br />
thread. Pada Solaris, pembuatan proses memakan waktu 30 kali lebih lama dibandingkan<br />
pembuatan thread sedangkan proses context switch 5 kali lebih lama dibandingkan context<br />
switching thread.<br />
d. Utilisasi arsitektur multiprosesor. Keuntungan dari multithreading dapat sangat meningkat<br />
pada arsitektur multiprosesor, dimana setiap thread dapat berjalan secara paralel di atas<br />
procesor yang berbeda. Pada arsitektur processor tunggal, CPU menjalankan setiap thread<br />
secara bergantian tetapi hal ini berlangsung sangat cepat sehingga menciptakan ilusi paralel,<br />
tetapi pada kenyataannya hanya satu thread yang dijalankan CPU pada satu-satuan waktu.<br />
Adapun kerugian dari multithreading adalah :<br />
1. Jika digunakan secara berlebihan, multithreading akan berdampak pada pemborosan<br />
resource dan CPU yang dialokasikan untuk switching threads. Misalnya jika heavy disk I/O<br />
terlibat, akan lebih cepat jika hanya memiliki 1 atau 2 thread yang melaksanakan tugas secara<br />
berurutan, daripada menggunakan multithread yang masing-masing mengeksekusi sebuah task<br />
pada waktu yang sama.
2. Sistem yang memiliki kecepatan prosesor dan memory yang cenderung sama, sehingga tidak<br />
ada efisiensi yang hilang (mengacu kepada latency), tidak akan memperoleh peningkatan<br />
bandwidth yang signifikan jika menggunakan multithreading.<br />
3. Multithreading menghasilkan program yang lebih kompleks. Menggunakan multiple thread<br />
sendiri tidak akan menciptakan kerumitan, tapi interaksi antar thread-lah yang mengakibatkan<br />
kompleksitas tersebut.<br />
4. <strong>Thread</strong> yang banyak bisa saling berinterferensi ketika saling berbagi sumber daya hardware<br />
seperti cache.<br />
11.3. Model Multi<strong>Thread</strong>ing<br />
Beberapa terminologi yang akan dibahas:<br />
a. <strong>Thread</strong> pengguna: <strong>Thread</strong> yang pengaturannya dilakukan oleh pustaka thread pada tingkatan<br />
pengguna. Karena pustaka yang menyediakan fasilitas untuk pembuatan dan penjadwalan<br />
thread, thread pengguna cepat dibuat dan dikendalikan.<br />
b. <strong>Thread</strong> Kernel: . <strong>Thread</strong> yang didukung langsung oleh kernel. Pembuatan, penjadwalan dan<br />
manajemen thread dilakukan oleh kernel pada kernel space. Karena dilakukan oleh sistem<br />
operasi, proses pembuatannya akan lebih lambat jika dibandingkan dengan thread pengguna.<br />
Gambar 11.1. Model-Model Multi<strong>Thread</strong>ing<br />
Model-Model Multi<strong>Thread</strong>ing:<br />
a. Model Many-to-One. Model ini memetakan beberapa thread tingkatan pengguna ke sebuah<br />
thread. tingkatan kernel. Pengaturan thread dilakukan dalam ruang pengguna sehingga efisien.<br />
Hanya satu thread pengguna yang dapat mengakses thread kernel pada satu saat. Jadi Multiple<br />
thread tidak dapat berjalan secara paralel pada multiprosesor. Kekurangannya adalah ketika ada<br />
satu blocking systemc call, semua akan menjadi terblok juga. Contoh: Solaris Green <strong>Thread</strong>s dan<br />
GNU Portable <strong>Thread</strong>s.<br />
b. Model One-to-One. Model ini memetakan setiap thread tingkatan pengguna ke setiap thread.<br />
Ia menyediakan lebih banyak concurrency dibandingkan model Many-to-One. Keuntungannya<br />
sama dengan keuntungan thread kernel. Kelemahan model ini ialah setiap pembuatan thread<br />
pengguna memerlukan tambahan thread kernel. Karena itu, jika mengimplementasikan sistem ini<br />
maka akan menurunkan kinerja dari sebuah aplikasi sehingga biasanya jumlah thread dibatasi<br />
dalam sistem. Contoh: Windows NT/XP/2000 , Linux, Solaris 9, OS/2.
c. Model Many-to-Many. Model ini memultipleks banyak thread tingkatan pengguna ke thread<br />
kernel yang jumlahnya sedikit atau sama dengan tingkatan pengguna. Model ini mengizinkan<br />
developer membuat thread sebanyak yang ia mau tetapi concurrency tidak dapat diperoleh<br />
karena hanya satu thread yang dapat dijadwalkan oleh kernel pada suatu waktu. Keuntungan<br />
dari sistem ini ialah kernel thread yang bersangkutan dapat berjalan secara paralel pada<br />
multiprosessor dan lebih efisien. Contoh : Solaris 2, IRIX, HPUX.<br />
11.4. Pustaka <strong>Thread</strong><br />
Pustaka <strong>Thread</strong> atau yang lebih familiar dikenal dengan <strong>Thread</strong> Library bertugas untuk<br />
menyediakan API untuk programmer dalam menciptakan dan memanage thread. Ada dua cara<br />
dalam mengimplementasikan pustaka thread:<br />
a. Menyediakan API dalam level pengguna tanpa dukungan dari kernel sehingga pemanggilan<br />
fungsi tidak melalui system call. Jadi, jika kita memanggil fungsi yang sudah ada di pustaka,<br />
maka akan menghasilkan pemanggilan fungsi call yang sifatnya lokal dan bukan system call.<br />
b. Menyediakan API di level kernel yang didukung secara langsung oleh sistem operasi.<br />
Pemanggilan fungsi call akan melibatkan system call ke kernel.<br />
Ada tiga pustaka thread yang sering digunakan saat ini, yaitu: POSIX Pthreads, Java, dan Win32.<br />
Implementasi POSIX standard dapat dengan cara user level dan kernel level, sedangkan Win32<br />
adalah kernel level. Java API thread dapat diimplementasikan oleh Pthreads atau Win32.<br />
11.5. Pembatalan <strong>Thread</strong><br />
<strong>Thread</strong> Cancellation ialah pembatalan thread sebelum tugasnya selesai. Misalnya hendak<br />
mematikan Java Virtual Machine (JVM) pada program Java. Maka sebelum JVM dimatikan<br />
seluruh thread yang berjalan harus dibatalkan terlebih dahulu. Contoh lain adalah pada masalah<br />
search. Apabila sebuah thread mencari sesuatu dalam database dan menemukan serta<br />
mengembalikan hasilnya, thread sisanya akan dibatalkan. <strong>Thread</strong> yang akan diberhentikan biasa<br />
disebut target thread.<br />
Pemberhentian target <strong>Thread</strong> dapat dilakukan dengan 2 cara:<br />
a. Asynchronous cancellation. Suatu thread seketika itu juga membatalkan target thread.<br />
b. Deferred cancellation. Suatu thread secara periodik memeriksa apakah ia harus batal, cara<br />
ini memperbolehkan target thread untuk membatalkan dirinya secara terurut.<br />
Hal yang sulit dari pembatalan thread ini adalah ketika terjadi situasi dimana sumber daya sudah<br />
dialokasikan untuk thread yang akan dibatalkan. Selain itu kesulitan lain adalah ketika thread<br />
yang dibatalkan sedang meng-update data yang ia bagi dengan thread lain. Hal ini akan menjadi<br />
masalah yang sulit apabila digunakan asynchronous cancellation. Sistem operasi akan<br />
mengambil kembali sumber daya dari thread yang dibatalkan tetapi seringkali sistem operasi<br />
tidak mengambil kembali semua sumber daya dari thread yang dibatalkan.<br />
Alternatifnya adalah dengan menggunakan deffered cancellation. Cara kerja dari deffered<br />
cancellation adalah dengan menggunakan satu thread yang berfungsi sebagai pengindikasi<br />
bahwa target thread hendak dibatalkan. Tetapi pembatalan hanya akan terjadi jika target thread<br />
memeriksa apakah ia harus batal atau tidak. Hal ini memperbolehkan thread untuk memeriksa<br />
apakah ia harus batal pada waktu dimana ia dapat dibatalkan secara aman yang aman. Pthread<br />
merujuk sebagai cancellation points.<br />
Pada umumnya sistem operasi memperbolehkan proses atau thread untuk dibatalkan secara<br />
asynchronous. Tetapi Pthread API menyediakan deferred cancellation. Hal ini berarti sistem<br />
operasi yang mengimplementasikan Pthread API akan mengizinkan deferred cancellation.
11.6. <strong>Thread</strong> Pools<br />
Pada web server yang menerapkan multithreading ada dua masalah yang timbul:<br />
a. Ukuran waktu yang diperlukan untuk menciptakan thread yang melayani permintaan yang<br />
diajukan pada kenyataannya thread dibuang seketika sesudah ia menyelesaikan tugasnya.<br />
b. Pembuatan thread yang tidak terbatas jumlahnya dapat menurunkan performa dari sistem.<br />
Solusinya adalah dengan penggunaan <strong>Thread</strong> Pools, yaitu sekumpulan thread yang mengantri<br />
untuk mengerjakan tugas Cara kerjanya adalah dengan membuat beberapa thread pada proses<br />
startup dan menempatkan mereka ke pools, dimana mereka duduk diam dan menunggu untuk<br />
bekerja. Jadi, ketika server menerima permintaan, ia akan membangunkan thread dari pool dan<br />
jika thread tersedia maka permintaan tersebut akan dilayani.<br />
Ketika thread sudah selesai mengerjakan tugasnya maka ia kembali ke pool dan menunggu<br />
pekerjaan lainnya. Bila tidak ada thread yang tersedia pada saat dibutuhkan maka server<br />
menunggu sampai ada satu thread yang bebas.<br />
Keuntungan thread pool adalah:<br />
a. Biasanya lebih cepat untuk melayani permintaan dengan thread yang ada dibandingkan<br />
menunggu thread baru dibuat.<br />
b. <strong>Thread</strong> pool membatasi jumlah thread yang ada pada suatu waktu. Hal ini penting pada sistem<br />
yang tidak dapat mendukung banyak thread yang berjalan secara concurrent. Jumlah thread<br />
dalam pool dapat tergantung dari jumlah CPU dalam sistem, jumlah memori fisik, dan jumlah<br />
permintaan klien yang concurrent.<br />
c. Pembuatan jumlah thread yang tepat dapat meningkatkan performa serta sistem yang lebih<br />
stabil
11.7. Penjadwalan <strong>Thread</strong><br />
Begitu dibuat, thread baru dapat dijalankan dengan berbagai macam penjadwalan. Kebijakan<br />
penjadwalanlah yang menentukan setiap proses, di mana proses tersebut akan ditaruh dalam<br />
daftar proses sesuai proritasnya dan bagaimana ia bergerak dalam daftar proses tersebut.<br />
Untuk menjadwalkan thread, sistem dengan model multithreading many to many atau many to<br />
one menggunakan:<br />
a. Process Contention Scope (PCS). Pustaka thread menjadwalkan thread pengguna untuk<br />
berjalan pada LWP (lightweight process) yang tersedia.<br />
b. System Contention Scope (SCS). SCS berfungsi untuk memilih satu dari banyak thread,<br />
kemudian menjadwalkannya ke satu thread tertentu (CPU / Kernel).<br />
Gambar 11.2. Penjadwalan <strong>Thread</strong>
11.8. <strong>Thread</strong> Linux<br />
Ketika pertama kali dikembangkan, Linux tidak didukung dengan threading di dalam kernelnya,<br />
tetapi dia mendukung proses-proses sebagai entitas yang dapat dijadwalkan melalui clone()<br />
system calls. Sekarang Linux mendukung penduplikasian proses menggunakan system call<br />
clone() dan fork(). Clone() mempunyai sifat mirip dengan fork(), kecuali dalam hal pembuatan<br />
salinan dari proses yang dipanggil dimana ia membuat sebuah proses yang terpisah yang<br />
berbagi address space dengan proses yang dipanggil. Pembagian address space dari parent<br />
process memungkinkan cloned task bersifat mirip dengan thread yang terpisah. Pembagian<br />
address space ini dimungkinkan karena proses direpresentasikan di dalam Kernel Linux. Di<br />
dalam Kernel Linux setiap proses direpresentasikan sebagai sebuah struktur data yang unik.<br />
Jadi, daripada menciptakan yang baru maka struktur data yang baru mengandung pointer yang<br />
menunjuk ke tempat dimana data berada. Jadi ketika fork() dipanggil, proses yang baru akan<br />
tercipta beserta duplikasi dari segala isi di struktur data di parent process, namun ketika clone()<br />
dipanggil, ia tidak menduplikasi parent process-nya tetapi menciptakan pointer ke struktur data<br />
pada parent process yang memungkinkan child process untuk berbagi memori dan sumber daya<br />
dari parent process-nya. Project Linux <strong>Thread</strong> menggunakan system call ini untuk mensimulasi<br />
thread di user space. Sayangnya, pendekatan ini mempunyai beberapa kekurangan, khususnya<br />
di area signal handling, scheduling, dan interprocess synchronization primitive.<br />
Untuk meningkatkan kemampuan <strong>Thread</strong> Linux, dukungan kernel dan penulisan ulang pustaka<br />
thread sangat diperlukan. Dua project yang saling bersaing menjawab tantangan ini. Sebuah tim<br />
yang terdiri dari pengembang dari IBM membuat NGPT (Next Generation POSIX <strong>Thread</strong>s).<br />
Sementara pengembang dari Red Hat membuat NPTL (Native POSIX <strong>Thread</strong> Library).<br />
Sebenarnya Linux tidak membedakan antara proses dan thread. Dalam kenyataannya, Linux<br />
lebih menggunakan istilah task dibandingkan proses dan thread ketika merujuk kepada<br />
pengaturan alur pengontrolan di dalam program.<br />
Pada sistem operasi lain seperti Mac OS X, terdapat lima thread API yang berbeda, yaitu: Mach<br />
thread, POSIX thread (pthreads), Cocoa thread (NS<strong>Thread</strong>s), Carbon MP tasks, dan Carbon<br />
<strong>Thread</strong> Manager. Akan tetapi tidak mudah untuk menentukan suatu thread mengerjakan tugas<br />
yang mana, sehingga dibuatlah suatu siklus yang membuat masing-masing thread bekerja<br />
secara bergantian.<br />
11.9. Rangkuman<br />
<strong>Thread</strong> adalah alur kontrol dari suatu proses.<br />
Keuntungan menggunakan Multithreading:<br />
a. Meningkatkan respon dari pengguna.<br />
b. Pembagian sumber daya.<br />
c. Ekonomis.<br />
d. Mengambil keuntungan dari arsitektur multiprosessor.<br />
Tiga model Multithreading:<br />
a. Model Many-to-One.<br />
b. Model One-to-One.<br />
c. Model Many-to-Many.<br />
Pustaka <strong>Thread</strong> bertugas untuk menyediakan API untuk programmer dalam menciptakan dan<br />
memanage thread. Cara untuk mengimplementasikannya yaitu:<br />
a. Menyediakan API dalam level pengguna tanpa dukungan dari kernel.<br />
b. Menyediakan API di level kernel yang didukung secara langsung oleh sistem operasi.
Pembatalan <strong>Thread</strong>: Tugas untuk membatalkan <strong>Thread</strong> sebelum menyelesaikan tugasnya.<br />
Pembatalan <strong>Thread</strong> terdiri dari 2 jenis:<br />
1. Asynchronous cancellation.<br />
2. Deffered cancellation.<br />
<strong>Thread</strong> Pools menciptakan sejumlah <strong>Thread</strong> yang ditempatkan di dalam pool dimana <strong>Thread</strong><br />
menunggu untuk dipanggil.<br />
<strong>Thread</strong> Schedulling ada 2 macam:<br />
1. Local Schedulling.<br />
2. Global Schedulling.<br />
Istilah thread di Linux adalah task.<br />
Pembuatan <strong>Thread</strong> di Linux menggunakan system call clone(). Sedangkan di Mac sekumpulan<br />
thread yang ada akan mengerjakan tugas bergantian dengan menggunakan siklus.
Rujukan<br />
[Silberschatz2005] Avi Silberschatz, Peter Galvin, dan Grag Gagne. 2005. Operating<br />
Systems Concepts. Seventh Edition. John Wiley & Sons.<br />
[WEBFSF1991a] Free Software Foundation. 1991. GNU General Public License –<br />
http://gnui.<strong>vLSM</strong>.org/ licenses/ gpl.txt . Diakses 29 Mei 2006.<br />
[WEBWIKI2007] Wikipedia. 2007. <strong>Thread</strong>_(computer_science) – http://en.wikipedia.org/<br />
wiki/<strong>Thread</strong>_(computer_science) . Diakses 16 Februari 2007.<br />
[WEBWIKI2007] Wikipedia.. 2007. Multiprocessing – http://en.wikipedia.org/ wiki/<br />
Multiprocessing . Diakses 16 Februari 2007.<br />
[WEBWIKI2007] Wikipedia.. 2007. Computer_multitasking – http://en.wikipedia.org/ wiki/<br />
Computer_mutitasking . Diakses 16 Februari 2007.<br />
[WEBIBM] IBM.. 2007. linux_threading – http://www-128.ibm.com/ developerworks/ java/<br />
library/j-prodcon . Diakses 16 Februari 2007.<br />
[WEBWIKI2008] Wikipedia.. 2008. <strong>Thread</strong>_pool_pattern – http://en.wikipedia.org/ wiki/<br />
<strong>Thread</strong>_pool_pattern . Diakses 8 April 2008.<br />
[WikiCH2008] Wikipedia, The Free Encyclopedia. 2008. Computer Hardware –<br />
http://en.wikipedia.org/wiki/Multithreading Diakses 7 April 2008<br />
[WikiCS2008] Wikipedia, The Free Encyclopedia. 2008. Computer Science –<br />
http://en.wikipedia.org/wiki/<strong>Thread</strong> Diakses 7 April 2008<br />
[TechnicalNote] Technical Note 2028. 2008. <strong>Thread</strong>ing Architectures –<br />
http://developer.apple.com/technotes/tn/tn2028.html. Diakses 9 April 2008
Hak Cipta © Mahasiswa Fakultas Ilmu Komputer Universitas Indonesia, peserta mata kuliah<br />
Sistem Operasi semester genap 2008<br />
1. Genta Moerita (A 0606104265)<br />
2. Yuan Hanif Syaniardi (B 0606031603)<br />
3. Yunus Kuntawi Aji (B 0606031616)<br />
Silakan menyalin, mengedarkan, dan/atau memodifikasi dokumen ini