Thread Kavramı 23 May 08, Friday @ 17:37

Thread nedir?

Thread (kanal), bir programda çalışacak komutlar dizisidir. UNIX işlemleri, main() fonksiyonuyla başlayan tek bir thread'den oluşur. Thread konseptinden önce birden çok komutu paralel olarak çalıştırmanın yolu, fork() ve exec() sistem fonksiyonlarını kullanmaktı. Ama thread mekanizmasını kullanarak, bir program içinde paralel olarak birden çok işi yapmak mümkündür. Ne var ki bunu yapmak, aşağıda değineceğimiz bazı özel durumlar nedeniyle dikkat isteyen bir iştir.

Neden thread kullanmalıyım sorusuna cevap vermek önemlidir. Bu mekanizma kullanılarak yazılan bir program, onsuz yazılan bir programdan hem daha zordur, hem de daha uzun zaman alır. Dolayısıyla eğer gerçekten kullanmanız gerekmiyorsa, thread kullanmaya çalışmak pek de verimli ve tavsiye edilecek bir durum değildir. Çünkü bu meka

Peki avantajları neler? Üç temel avantajdan bahsedebiliriz: hız, girdi-çıktı verimi ve taşınabilirlik. Bunları tek tek incelersek:

Hız: Threadler arasında iletişim oldukça hızlıdır. Eğer algoritmanız hızlı iletişim gerektiriyorsa thread mekanizmasını kullanmak için iyi bir sebebiniz var demektir.

Girdi-Çıktı(I/O) verimi: Normal bir UNIX işleminde, bloklanmış bir girdi-çıktı isteği bütün işlemin durmasına ya da beklemesine sebep olabilir. Ama thread mekanizmasında bir bloklama isteği sadece isteği yapan thread'i ilgilendirdiği için programın geri kalanı bundan etkilenmez.

Taşınabilirlik: POSIX thread'ler, çok az bir hız kaybıyla farklı platformlara taşınabilir. Burada taşınabilirlikten kasıt farklı işletim sistemlerinden çok farklı mimarilerdir.

Thread tanımlaması

Nasıl her işlemin(process) bir işlem tanımlayıcısı (ID) varsa, thread'lerin de IDsi vardır. Aralarındaki fark şu ki process kimlikleri sistem bazında verilirken, thread kimlikleri ait oldukları process bazında verilir.

Thread kimliklerinin veri türü 'pthread_t' dir. Bu veri türüne integer türü gibi davranmak ve bu mantıkla üzerinde işlem yapmak mümkün değildir. Ama thread kimliklerini karşılaştırmak için de fonksiyon vardır.



#include <pthread.h> //eşitse sıfır, değilse sıfır harici değer döner

int pthread_equal(pthread_t tid1,pthread_t tid2);

 

pthread_t, bir yapıdır(struct). Yapı olması nedeniyle de değerini yazdırmanın taşınabilir bir yöntemi yoktur.

Bir thread'in ID'sini pthread_self fonksiyonu ile elde eder.



#include <pthread.h>

pthread_t pthread_self(void);



Thread yaratmak

Unix process modelinde, her process sadece bir thread kontrol eder. Thread tabanlı modelde de aynı durum geçerlidir. Her process sadece bir thread'den oluşur. Yeni thread'ler program çalışırken oluşur.

Yeni bir thread, pthread_create fonksiyonuyla yaratılır.



#include <pthread.h>

int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr,

void *(*start_rtn) (void), (void) *restrict arg);



tidp ile gösterilen hafıza adresi, yeni yaratılan thread'in ID'sini tutar. Yaratılan thread'in başlangıç adresi start_rtn'dir.

Bir thread yaratıldığında hangi thread'in önce çalışacağı konusunda bir garanti yoktur. yaratılan thread de olabilir çağıran thread de. Yeni yaratılan thread, yaratan thread'in adres alanına erişebilir. Ama bekleyen sinyal listesi bu thread için temizlenir.

pthread fonksiyonları, hata olduğunda “errno” kullanmak yerine bir hata kodu dönerler.

thread yarattığınız zaman, main fonksiyonununzda bir sleep kullanmanız tavsiye edilir. Çünkü ana işleminiz bir thread bitmeden önce bitebilir, bu da hataya sebep olur.

Thread yok etmek

Bir işlem içinde herhangi bir thread exit, _Exit ya da _exit fonksiyonlarından birini çağırırsa, bütün işlem sonlandırılır.

Bütün işlemi sonlandırmadan bir thread'i sonlandırmanın ise üç yolu vardır:

  1. thread, start rutininden döner. Dönüş değeri thread'in exit kodudur.

  2. Bir thread, aynı işlemdeki bir thread tarafından iptal edilir.

  3. thread, pthread_exit fonksiyonunu çağırır.



#include <pthread.h>

void pthread_exit(void * rval_ptr);



Buradaki rval_ptr, türü olmayan bir göstericidir. Bu gösterici, işlemlerdeki diğer thread'ler tarafından pthread_join fonksiyonu sayesinde erişilebilir.



#include <pthread.h>

int pthread_join(pthread_t thread, void **rval_ptr);



Bu fonksiyonun detaylarını incelemenizi tavsiye ederim.



Bir thread, aynı işlemdeki başka bir thread'i pthread_cancel fonksiyonu ile yokedebilir.

 

#include <pthread.h>

int pthread_cancel(pthread_t tid);



Thread senkronizasyonu

Multi-thread programlar yazarken en kritik nokta, paylaşılan bilgilerin kontrolüdür. Eğer bir thread diğer thread'lerin üzerinde değişiklik yapamayacağı bir veriyi okuyorsa sorun yoktur. Ama bir threadin okuduğu veriyi başka bir thread'in değiştirebilme yeteneği varsa bu noktada dikkat edilmesi gerekir. Çünkü birinin okuduğu değeri diğeri değiştirdiğinde tutarsızlık olur ve bu da programınızın düzgün çalışmasını (belkide çalışmasını) engeller.

Bu sorunu aşmanın çeşitli yolları vardır. Biri bilgisayar mimarisini buna göre düzenlemektir ki bir yazılımcı bunun varolduğuna güvenemez. İkinci yol değiştirilen değerlere kilit koymaktır(lock). Ayrıca thread senkronizasyonu da bir yöntemdir. Senkronizasyon en kısa tabiriyle thread'lerin bir değişiklik yapacakları zaman diğer thread'lerle birlikte hareket etmesi ve birinin yaptığı değişiklikten diğerlerinin de haberdar edilmesidir.

Kısa bir İnternet araştırması sonucu bu konuyla ilgili birçok örnek kod bulabilirsiniz.

Mutex

pthread mutex(mutual-exclusion) kullanarak verilerin aynı anda sadece bir thread tarafından değiştirilebileceğini garanti ederek verileri koruyabiliriz. Mutex, bir veriyi değiştirmeden hemen önce diğer thread'lerin veriye erişimini engellemek üzere konulan bir kilit olarak ifade edilebilir.

Mutex mekanizması sadece thread'lerin aynı veri erişimi kurallarını uyguladığı durumlarda işe yarar.

Mutex değişkenleri, pthread_mutex veri türüyle ifade edilir. Mutex kullanmadan önce ya PTHREAD_MUTEX_INITIALIZER sabiti ya da pthread_mutex_init fonksiyonu ile başlatılmalıdır. Eğer mutex, malloc kullanarak dinamik olarak yerleştirildiyse, hafızayı boşaltmadan önce pthread_mutex_destroy fonksiyonu çağrılmalıdır.



#include <pthread.h>

int pthread_mutex_init (pthread_mutex_t *restrict mutex,

const pthread_mutexattr_t *restrict attr);

int pthread_mutex_destroy (pthread_mutex_t *mutex);



Yukarıda bahsettiğim kilitleme işlemlerini gerçekleştirmek için de aşağıdaki fonksiyonlar kullanılır.



#include <pthread.h>

int pthread_mutex_lock (pthread_mutex_t *mutex);

int pthread_mutex_trylock (pthread_mutex_t *mutex);

int pthread_mutex_unlock (pthread_mutex_t *mutex);



Multithread programlama burada bahsettiğimden çok daha uzun bir konudur. Bu sebeple benim yazımı bir başlangıç yazısı ya da kavramlar açısından yol gösterici olarak kabul etmenizi ve konuyu özellikle örnek kodlar inceleyerek daha detaylı ele almanızı tavsiye ederim. Çünkü mutlthread programlama, tehlikeli programlama tekniklerinden biridir. Araştırmalarınız için diğer birçok konuda olduğu gibi bu konuda da güzel bir başlangıç noktasına sahipsiniz: man pthread.h (Tabi eğer Linux kullanıcısı iseniz:D)



Tags: Programlama  Linux  thread   ,  Comments: 0 ( Add your comment )
LD PRELOAD 20 May 08, Tuesday @ 22:39


Paylaşılan Kütüphane (shared library) nedir?

Paylaşılan kütüphaneler (shared libraries), programlar çalıştığında programlar tarafından yüklenen kütüphanelerdir. bu kütüphaneler, işletim sistemine bir kere kurulur, daha sonra kurulan programlar bu kurulan kütüphaneleri kullanır. Daha sonra kütüphanenin yeni sürümü kurulursa bile, programlar eski sürümü kullanmaya devam edebilir. programlar çalıştığı sırada dinamik olarak çağırılan bu kütüphaneler, çalışma hızını büyük ölçüde arttırır.

bu kütüphaneler “lib” harfleriyle başlar ve uzantıları “.so” olur. Eğer kendiniz bir paylaşılan kütüphane yarattıysanız, bu kütüphaneyi yüklemek için gereken dosyaları soğru yerlere kopyaladıktan sonra ldconfig komutunu çalıştırmalısınız.

ldconfig -n paylaşılan_kütüphanenin_yolu



Dinamik bağlama (dynamic linking) nedir?

Eğer programınız bir paylaşılan kütüphane kullanıyorsa, derlerken bunu belirtmeniz gerekir. Örneğin programınızda ssl kütüphanesini kullanmanız gerekiyorsa, libssl.so kütüphanesini kullanmalısınız. Bunu yapmak için de programınızı derlerken -lssl ifadesini eklemeniz gerekir.

gcc programismi.c -lssl



Bunu yaptığınız zaman, ssl kütüphanesindeki kodları yazılımınıza eklemediğiniz halde kullanabilirsiniz. Bu kütüphane, program çalıştığı sırada çağırıldığı için, libssl.so kütüphanesinin bulunduğu herhangi bir makinede programınızı çalıştırabilirsiniz.

LD_PRELOAD nedir?

LD_PRELOAD, kullanıcı tarafından belirlenmiş, boşluk karakteriyle ayrılmış, diğer kütüphanelerden önce yüklenen ELF paylaşılan kütüphaneler listesidir. Bu özellik, diğer paylaşılan kütüphanelerdeki fonksiyonların yerine geçen fonksiyonlar üretmek için kullanılabilir.

LD_PRELOAD ile çalıştırılan bir program X fonksiyonunu çağırıyorsa ve X fonksiyonu da LD_PRELOAD listesinde varsa, bu fonksiyon çağırılır. Eğer LD_PRELOAD listesinde X fonksiyonu yoksa, X genel arama yollarında aranır(/usr/lib/ , /usr/local/lib gibi)

 

.so objesi yaratmak

Daha önce de belirttiğim gibi, .so objesi, paylaşılan kütüphanelerin uzantısıdır. paylaşılan bir kütüphanenin diğer C ve C++ ile yazılmış programlar gibi bir 'main' fonksiyonuna ihtiyacı yoktur. Çünkü bu kütüphaneler kendi başına bir program değil, programlar tarafından kullanılan kodların paketidir.

LD_PRELOAD için .so dosyası yaratmak için tek ihtiyacınız yazdığınız kaynak kodu ve gcc derleyicisidir. Eğer her ikisine de sahipseniz, örnek olarak aşağıda verdiğim komutları çalıştırmanız yeterli olacaktır.

 

gcc -fPIC -rdynamic -c source_code.c

gcc -shared -o libsource_code.so source_code.o -lc -ldl



Tek tek hangi parametrenin ne işe yaradığını anlatmayacağım. Bunun için gcc'yi incelemenizi tavsiye ederim. Diğer tüm UNIX işlerinde olduğu gibi, bunda da “man gcc” size yol gösterecektir. Ama kısaca şunları söyleyebilirim. İlk satır kaynak kodunuzu derleyip bir .o uzantılı dosya oluşturmanızı sağlar (bu örnekte source_code.o) İkinci satırda ise bu .o uzantılı dosya sayesinde .so uzantılı dosyanızı üretirsiniz. Bu kadar basit.

LD_PRELOAD'a eklemek

.so uzantılı bir dosya ürettiniz. Peki bunu nasıl kullanacaksınız? Çok basit. bu dosyanın yolunu LD_PRELOAD listesine ekleyerek. Fakat burada dikkat edilmesi gereken çok önemli bir ayrıntı var. Bir fonksiyon hem LD_PRELOAD listesinde hem de başka herhangi bir yerde (örneğin /usr/lib/) varsa, LD_PRELOAD listesindeki fonksiyonun önceliği vardır. Yani örneğin siz fopen fonksiyonunu yeniden yazıp bunu da LD_PRELOAD listesine eklerseniz, artık fopen kullanılan bütün programlar bu listede belirtilen halini kullanır.

Bu uyarıyı yaptıktan sonra, bir kütüphanenin nasıl LD_PRELOAD listesine ekleneceğini yazıyorum. Burada yazdığım, listeye kalıcı olarak eklemek içindir. Bir sonraki bölümde tek kullanımlık halini yazacağım.



export LD_PRELOAD=/libx.so'nun/yolu/



LD_PRELOAD kullanımı

Öncelikle neden LD_PRELOAD kullanılır, bu sorunun cevabını verelim. En önemli avantajı, dinamik bağlanmış çalıştırılabilir programda hiçbir değişiklik yapmadan kullanılabilmesidir. Sadece dinamik kütüphaneyi değiştirerek, asıl yazılımınızda hiçbir değişiklik yapmadan programınızı yeniden düzenleyebilirsiniz.

LD_PRELOAD kullanmanın dezavantajı ise, kullanmak istediğiniz fonksiyona sahip kütüphanenin, program çalıştırıldığı sırada kurulu ve hazır olmasının gerekliliğidir.

Şimdi örnek bir LD_PRELOAD kullanımına geçelim:

LD_LIBRARY_PATH=. LD_PRELOAD=libsource_code.so ./program [varsa argüman]



Bu şekilde, programda eğer libsource_code.so'nun sahip olduğu bir fonksiyon çağırılıyorsa, bunu LD_PRELOAD ile çağıracaktır. Ama bu sadece yukardaki komutu yazdığımız zaman geçerlidir. Kalıcı bir kütüphane ekleme değildir.

Örnek

// target.c
#include <stdio.h>
#include <unistd.h>

int main() {
printf( "user id: %d\n", getuid() );
return 0;
}

Yukarıdaki kodu

gcc target.c -o target

komutuyla derleyip

./target

yazdığınızda, şuna benzer bir çıktı alırsınız:

$./target
user id: 1000

Buradaki 1000 değeri yerine getuid() fonksiyonunun döndüğü değer gelir. Eğer her zaman 0 dönmesini isterseniz



// libfake.c

int getuid() {
return 0;
}



kodunu yazıp,

$ gcc -shared libfake.c -o libfake.so

komutunu çalıştırın. Artık bir .so dosyanız var. bunu LD_PRELOAD listesine eklediğinizde

$ LD_PRELOAD=./libfake.so ./target
user id: 0

alırsınız.



shared library --> http://www.dwheeler.com/program-library/Program-Library-HOWTO/x36.html

ldconfig --> http://linux.die.net/man/8/ldconfig

LD_PRELOAD man page --> http://unixhelp.ed.ac.uk/CGI/man-cgi?ld.so+8

gcc --> http://gcc.gnu.org/





Tags: Linux  ld preload  shared object  shared library   ,  Comments: 0 ( Add your comment )
RPM Oluşturmak 06 February 08, Wednesday @ 13:09

Linux kullanıcılarının (en azından bir kısmının) görmeye alışkın olduğu bir paket türü vardır: RPM

RPM haline getirilmiş bir paketi kurmak genellikle zor değildir. Paketi hazırlayan kişi ya da kişiler zaten sizin işinizi en kolay şekilde halletmeniz için uğraşmış oluyorlar. Peki biz kendimiz bu paketlerden hazırlamak için ne yapmalıyız?

Aşağıda yazdıklarım adım adım takip edeceğiniz bir kılavuz değildir. Ama RPM paketleri hazırlamak istiyorsanız mutlaka bilmeniz gereken konuları anlatacağım. Detaylarla ilgili aklınıza takılan sorular olursa serdar.tugcu[at]portakalteknoloji.com adresine mail atabilirsiniz.

  1. RPM nedir?

RPM(Rad Hat Package Manager), Red Hat tarafından geliştirilen bir paket yönetim sistemidir. Bu sistem hem sistemdeki paketleri yönetmek, hem de yeni paketler oluşturmak için kullanılabilir. Bu paketler sadece sizin program kurmanızı kolaylaştırmakla kalmaz, aynı zamanda kurduğunuz programın sistem tarafından daha kolay tanınmasını da sağlar.

  1. RPM paketi nasıl kurulur?

RPM paketi kurmak günümüzdeki linux sürümlerinde sadece arayüzle bile yapılabilen bir iştir. Fakat komut satırından kurmak da hiç de zor değildir.


rpm –I [packagename].rpm


Eğer daha önceden kurduğunuz bir paketi yükseltmek istiyorsanız, -U parametresiyle amacınıza ulaşabilirsiniz.


rpm –U [packagename].rpm


  1. Kurulmuş paket nasıl kaldırılır?

Daha önceden kurulan bir paketi kaldırmak oldukça kolay bir iştir. Tek yapmanız gereken –i parametresini kullanmaktır.


rpm –e [packagename].rpm


  1. RPM nasıl oluşturulur?

Geldik işin en önemlli kısımına. RPM nasıl oluşturulur? Öncelikle, RPM paketini oluşturacağınız kodun sorunsuz derlenebilen bir kod olması gerekir. Malum koda sahip olduğunuzu varsayarak devam ediyorum:

Bir RPM paketi oluşturmak istiyorsanız, temel olarak iki şeye ihtiyacınız vardır: kaynak kodları ve paketiniz için yazılmış bir SPEC dosyası. Kaynak kodunuzda bir sorun olmadığından yola çıkarak, SPEC dosyasından işe girişelim.

SPEC dosyası, yazılımınızın nasıl ve nereye kurulacağına, hangi ek özelliklere sahip olması gerektiğine ve buna benzer bilgilere sahip olan dosyadır. SPEC dosyasının alışılan isimlendirme yöntemi şudur:

[isim]-[versiyon]-[sürüm numarası].spec

Yukarıdaki yapı zorunlu olduğunuz bir yapı değildir. Fakat yazılımcılar iyi bilir ki mevcut yazılımınız asla son sürüm değildir. Farklı sürümlerin spec dosyaları arasında kaybolmamanız için bu yapıyı tavsiye ediyorum.

Örnek bir SPEC dosyası şablonu:


Summary: [Yazılımın özetini yapan yazılar]

Name: [Yazılımın ismi]

Version: [versiyonu]

Release: [sürüm]

Copyright: [Genellikle GPL olur ]

Group: [sistemin hangi grubuna gireceği]

Source: [kaynak kodunun yolu]

BuildRoot: [kaynak kodunun derleneceği yol]


%description

[Yazılımla ilgili açıklama burada yapılacaktır]


%prep

%setup -q

%patch -p1 -b .buildroot


%build

make RPM_OPT_FLAGS="$RPM_OPT_FLAGS"


%install

rm -rf $RPM_BUILD_ROOT

mkdir -p $RPM_BUILD_ROOT/usr/bin

mkdir -p $RPM_BUILD_ROOT/usr/man/man1


install -s -m 755 [isim] $RPM_BUILD_ROOT/usr/bin/[isim]

install -m 644 [isim].1 $RPM_BUILD_ROOT/usr/man/man1/[isim].1


%clean

rm -rf $RPM_BUILD_ROOT


%files

%defattr(-,root,root)

%doc README TODO COPYING ChangeLog


/usr/bin/[isim]

/usr/man/man1/[isim]


%changelog

[değişiklik yapılacaksa, açıklamalar burada yazılır]


Header (Başlık) kısmı:

Summary: Paketin tek satırlık açıklaması

Name: RPM paketinin ismi

Version: Versiyon numarası

Release: Sürüm numarası

Copyright: Yazılımın yayın hakkı türü

Group: Paketin dahil olduğu grup

Source: Kaynak kodlarının yolu [ya da ismi]

Patch: Yamayı bulabileceğiniz yer



İlk beş başlığın açıklamaya ihtiyaç duymadığını düşünüyorum. Bu nedenle ilk olarak Group başlığını açıklamaya başlıyorum:

Group:

Programın nereye kurulması gerektiğini belirten başlık. Başlıkların neler olduğunu görmeniz için aşağıdaki tabloya bakınız.

Amusements/Games

Amusements/Graphics

Applications/Archiving

Applications/Communications

Applications/Databases

Applications/Editors

Applications/Emulators

Applications/Engineering

Applications/File

Applications/Internet

Applications/Multimedia

Applications/Productivity

Applications/Publishing

Applications/System

Applications/Text

Development/Debuggers

Development/Languages

Development/Libraries

Development/System

Development/Tools

Documentation

System Environment/Base

System Environment/Daemons

System Environment/Kernel

System Environment/Libraries

System Environment/Shells

User Interface/Desktops

User Interface/X

User Interface/X Hardware Support

Buildroot:

Bu başlık, sizin bir klasörü derleme ve yükleme için kök dizini olarak belirlemenizi sağlar. Bu başlık sizin paketi son yüklemeden önce denemenize izin verir.


%description:

Bu aslında gerçek bir başlık değildir. Yazılımınızın açıklamasını buraya yazmalısınız.

Prep (hazırlık) kısmı:

Bu bölüm, kaynak kodlarının derlemeye hazır hale getirildiği bölümdür. Bu bölümde herşeyi doğru yaparsanız, programınızın ‘make’ komutuna hazır hale gelmesini sağlarsınız.

Burada şunu da belirtmeliyim:

%prep kısmı, temel olarak hazırlık kısmıdır. Dolayısıyla bu kısım sistemi de derlemeye hazır hale getirmenizi sağlayan kısımdır. Dolayısıyla kabuk komutları bu bölümde çalıştırılabilir. Bir sh script yazıp bunu %prep etiketinin altına yerleştirerek çalışmasını sağlayabilirsiniz.

Bu kısımda kullanabileceğiniz bazı makrolar vardır.

Bunlardan ilki %setup makrosudur. Bu makro, kaynak kodlarını açar ve kaynak kodlarının açıldığı dizine gider. %setup makrosuyla birlikte kullanabileceğiniz bazı parametreler de mevcuttur. Bu parametreletden işinize yarayanları eklemek hayatınızı kolaylaştıracaktır.

%patch makrosu da kaynaklarınıza yama eklemenizi sağlar. Bu makro da bazı parametreler alabilir.

Bu makrolardan sonra da yazdığınız sh scriptlerini ekleyebilirsiniz. %build kısmına gelene kadar eklediğiniz herhangi bir satır eğer bir yorum satırı değilse sh vasıtasıyla çalışacağını da unutmayın.


Build:

Burada kullanabileceğiniz herhangi bir makro yoktur. Bir önceki kısımda kaynak kodlarınızı açıp, onların bulunduğu dizine gitmiştiniz. Buraya yazacaklarınız da sh kullanılarak çalıştırılır ve kodunuzun derlenmesini sağlar.


Install:

Bu kısımda da makro kullanımı yoktur. Eğer doğru bir şekilde buraya geldiyseniz, kaynak kodunuz derlenmiş demektir. Buraya yazacağınız satırlar, derlenen kodun yüklenmesini sağlar. Mesela Linux için hazırlanmış yazılımlarda sıkça kullanılan “make install” komutunu çalıştırmak istiyorsanız, burada çalıştırabilirsiniz.


Sistemi temizlemek(Clean):

İşiniz bittiğinde sistemi temizlemek her zaman için iyi bir alışkanlıktır. Bunun için de bu kısma komutlar yazarak istemediğiniz dosyaları ya da klasörleri silebilir, sisteminizi bir sonraki paket kurulumları için temiz hale getirebilirsiniz.


Yukarıda anlatılanlar, RPM paketi yapma konusunda size sadece fikir vermek ve temel bilgi oluşturmak için yazılmıştır. Daha detaylı bilgi edinmek isterseniz bu konuyla ilgili kaynak kitapların ilgili bölümüne başvurmanızı tavsiye ederim. Ayrıca diğer bütün Linux işlerinde olduğu gibi “man” komutunu da unutmamanızı tavsiye ederim. Ayrıca serdar.tugcu[at]portakalteknoloji.com adresinden bana ulaşabilir, sorularınızı gönderebilirsiniz.



Tags: Linux  RPM paketi   ,  Comments: 1 ( Add your comment )
wxWidgets 08 January 08, Tuesday @ 10:07

Son kullanıcı yazılımın detayını bilmez. Kurduğu programda iki şey bekler: Hızlı çalışsın ve rahat kullanılsın.

Hızlı çalışması, programı yazan yazılımcının zaten üstüne çok düşündüğü işler arasındadır. Tasarım sürecinde hızlı ve verimli çalışan bir program yazabilmek için elinden geleni yapar. Ama raht kullanılabilen, kullanıcı dostu, bir program, arayüzle ilgilidir. Kod yazarken her türlü cambazlıklardan ayrı bir zevk alan yazılımcılar, nedense arayüz tasarlarken sürükle-bırak tarzı ve arayüzle programın iletişimini en kolay şekilde sağlayabileceği araçları tercih eder.

İşte bu araçlar içinde sektörde daha çok tercih edilen birkaç araç vardır. Yazılımı yapan kişi olarak, sizin ihtiyacınıza göre bunlardan birini tercih edersiniz. Ben en çok önem verdiğim konulardan biri taşınabilirlik, yani hazırlanan arayüzün farklı işletim sistemlerinde çalışabilme yeteneğine sahip olması, olduğu için en çok Qt ve WxWidgets severim. Bu yazının konusu da WxWidgets ve bunun Qt ile karşılaştırması.

WxWidgets nedir?

wxWidgets, 1992 yılında Edinburg Üniversitesinde Julian Smart tarafından başlatıldı. İlk olarak Unix ve Windows'ta çalışan uygulamalar geliştirmek için başlatılan bir proje olmasına rağmen zamanla gelişerek Mac platformu, WinCE, ve başka birçok platformda çalışabilir hale getirildi. Açık kaynak kodlu olması sebebiyle çok hızlı gelişen, AOL gibi önemli firmalar tarafından da kullanılan bir araç olarak her geçen gün biraz daha güçlenmekte.

wxWidgets, programcının grafik arayüzüne sahip uygulamalar hazırlaması için bir araçtır. wxWidgets, birçok sınıf ve metot bulunan bir kütüphaneye sahiptir. WxWidget, dosyalar, çok kanallılık, uygulama ayarları, süreçlerarası iletişim, veritabanı erişimi ve benzeri birçok yaygın işle ilgili sınıflara sahiptir.

wxWidgets,platformun kendi kütüphanelerini kullanması sayesinde, hangi platformda çalışıyorsa o platformun görüntüsünü sağlayabilmektedir. Tek ihtiyacı olan gerekli kütüphanelerle bağlantı ve bir adet C++ derleyicisi. Bu sayede OS X üzerinde Aqua, Linux üzerinde GTK ya da Motif gibi her platformda platformun kendi arayüz özelliklerini kullanır.

wxwidgets, bedava ve açık kaynak kodludur. Bu wxWidgets'ın sadece maliyet düşürmek için kullanılması gerektiği anlamına gelmez. Aksine, diğer bütün açık kaynak kodlu yazılımlar gibi,açık kaynak kodlu yazılımlara gönül vermiş birçok deneyimli ve yetkin yazılımcının desteğini alarak, gücünü arttırması, wxWidgets'ı güncel ve ihtiyaçları fazlasıyla karşılayan bir yazılım halini alıyor.

wxWidgets, MFC'nin kullandığına benzer bir olay sistemine sahiptir. Bu sistem, olayları üye fonksiyonlarla statik ya da dinamik olarak ilişkilendirmeye izin verir.

 

Çok dil desteği:

wxWidgets genellikle C++ ile birlikte anılır. Fakat bunun yanında başka dillere de destek verir. Bu dillerden bazı yaygın olanları; Perl, Python, Ruby, Basic, JavaScript. Ayrıca Java ile birlikte kullanılması için de çalışılıyor.

Araçlar:

wxWidgets için uygun olan araçlardan en yaygın olanları wxDesigner, DialogBlocks, ve wxDev-C++. Başka araçlar da vardır ve açık kaynak kodlu olduğu için yeni ihtiyaçlara göre yeni seçeneklerin de karşımıza çıkması şaşırtıcı olmaz.

 

wxWidgets Qt karşılaştırması:

  • Hem wxWidgets, hem Qt arayüzle ilgisi olmayan özelliklere de sahiptir.(tarih, ağ, openGL özellikleri gibi)

  • Qt3, Mac ve Unix platformlarında geliştirilen açık kaynak kodlu uygulamalar için GPL lisansına sahiptir. Ticari uygulamalar ve Windows üzerinde geliştirilen her türlü uygulamalar için ise QPL lisansı vardır. Qt4'ün Windows için GPL lisansı vardır. Fakat wxWidgets her platformdaki ticari ya da ticari olmayan her uygulama için değiştirilmiş bir LGPL lisansına sahiptir ve uygulama geliştiriciler için herhangi bir lisans sorunu yoktur.

  • QT, wxWidgets gibi yerel portlara sahip değildir. Yani her ne kadar gerçekçi çizimler elde edebiliyor olsa da Qt her platformda kendi arayüz parçalarını(widget) çizer. Arayüz parçalarının programın kendisiyle iletişimini bizzat Qt yapar. Benzer bir özellik, wxUniversal ile birlikte wxWidget tarafından da kazanılmıştır. Ayrıca diğer platformlar için Qt'nin arayüz parçaları yerel değildir fakat KDE ve Qtopia platformları için bunlar yereldir.

  • wxWidgets, AOL Communicator gibi bazı büyük projeler tarafından kullanılmaktadır, fakat QT bu tür büyük çaplı projelerde daha yaygın olarak kullanılmaktadır.

  • Qt'nin sanal fonksiyonları, onu daha nesne yönelimli bir merkeze çeker. Burada ortaya çıkan fark şudur: Qt ile yazılan kodlar daha kısadır fakat wxWidgets daha hızlı çalışır.

  • Qt, QtDesigner adında bir arayüz tasarlama aracına sahiptir. wxWidgets ise bu konuda birden fazla seçenek sunar.

  • wxWidgets başka kütüphaneleri kullanabildiği için, Qt gibi görünen wxWidgets programları yazmak da mümkündür.

Sonuç:

Bu yazıda wxWidgets'ın ne olduğunu anlatmaya çalıştım. Vakit bulabilirsem ilerde daha detaylı ve teknik bir yazı da hazırlar, wxWidgets'ı kullanmaya karar veren insanlarayardımcı olmaya çalışırım.

Son bölümde sadece Qt ile karşılaştırmamın sebebi, halen en çok bilinen ve kullanılan alternatifin Qt olmasıdır. Nette kısa bir arama sonucunda diğer alternatiflerle de karşılaştırmalar bulabilirsiniz.

 



Tags: Programlama  wxWidgets  Arayüz Programlama   ,  Comments: 1 ( Add your comment )
4 result(s) in 1 page(s)
Previous Page  - 1 / 1 -  Next Page