C'de Thread Kullanımı hakkında soru?

Başlatan yamak, 03 Haziran 2013, 15:08:37

yamak

Örneğin aşağıdaki gibi bir programım var.Burda counter değeri 4'e ulaştığında her iki thread in sonlanıp ekrana "bitti" yazmasını istiyorum.Ama bi türlü thread'leri sonladıramadım.Programın çıktısı aşağıdaki gibi oluyo fakat "bitti" yazmıyo.
Alıntı YapCounter value: 1
Fonk calisti
Counter value: 2
Fonk calisti
Counter value: 3
Fonk calisti
Counter value: 4
Fonk calisti
Threadleri sonlandırmak için ne yapmam gerekiyo?


Kodlar:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
 void*  functionc(void);
 void* fonk(void);
 void* init(void);
 pthread_mutex_t mutex1= PTHREAD_MUTEX_INITIALIZER;
 pthread_cond_t  condition_var1   = PTHREAD_COND_INITIALIZER;
  pthread_cond_t  condition_var2   = PTHREAD_COND_INITIALIZER;
   pthread_t thread1,thread2;
 int counter=0;
int x=0,y=0;
int main(void)
{
    int rc1,rc2;
    if(rc1=pthread_create(&thread1,NULL,&functionc,NULL))
       printf("Thread1 olusturulamadi\n");
    if(rc2=pthread_create(&thread2,NULL,&fonk,NULL))
        printf("Thread1 olusturulamadi\n");
    pthread_join(thread1,NULL);
    pthread_join(thread2,NULL);
    printf("bitti\n");
    sleep(2);

}
void *functionc(void)
{

    while(1)
    {
        pthread_mutex_lock(&mutex1 );
        pthread_cond_wait(&condition_var1,&mutex1);
        counter++;
         printf("Counter value: %d\n",counter);
         x=1;
         if(counter==5)
         {
             pthread_cancel(thread1);
             break;
         }
         sleep(1);

        pthread_mutex_unlock( &mutex1 );
    }
    printf("fonk1 bitti");
}
void* fonk(void)
{
    while(1)
    {
        pthread_mutex_lock( &mutex1 );
        if(x==0)
        {
            pthread_cond_signal( &condition_var1 );
        }
        else
        {
            printf("Fonk calisti\n");
            if(counter==4)
            {
                pthread_cond_signal( &condition_var1 );
               break;
            }
            x=0;
        }

        pthread_mutex_unlock( &mutex1 );
    }

}

fatih6761

Threadlerin kod bloğunda while döngüsünü 1 yapmak yerine bir bayrağa/değişkene bağlayın. break yerine o değişkeni 0 yaparak döngüden çıkın, en sağlıklısı bu yöntem denebilir.

Gökhan BEKEN

Bence thread kullanmayın hocam.

Alıntı Yapc# dilinde

System.Threading.Thread.Sleep(x);
komutunu kullanarak "x" milisaniye kadar bekletme yapabiliriz ancak bu süre boyunca programımız donar. Bu hiç hoş olmayan bir yöntemdir. Konsol uygulamalarında çok fazla önemli olmasada visual ortamda kaçınmak gerekir.  Kaçınmak gerekir de nasıl bekleteceğiz?

Beklemenin başladığı zamanı(saati) biliyoruz. Ne kadar bekleyeceğimizide bildiğimize göre, sürenin başlangıç saati ile bekleyeceğimiz kadar süreyi toplarız, bu da bizim bitiş saatimizi(zamanımızı) verir. Bir fonksiyon yazar, istediğimiz bitiş zamanına gelmişmi diye kontrol ettirirsek programı dondurmadan bekleme yapabiliriz.

privatevoid Form1_Load(object sender, EventArgs e)
{
MessageBox.Show("Gecikme Başlıyor");
gecikme(10);
MessageBox.Show("gecikme bitti");
}
publicvoid gecikme(int saniye)
{
saniye = ((saniye +Convert.ToInt32(DateTime.Now.Second))%60);
for (; ; )
{
if (saniye == DateTime.Now.Second) break;
}
}
linkteki sayfaya daha önce yazmıştım: http://gokhanbeken.com/?p=582
Özel mesaj okumuyorum, lütfen göndermeyin.

yamak

Hocam yazınızı okudum siz orda sleep kullanmayın demişsiniz. Ben sleep kullanımından bahsetmedim zaten.Hatta yazınızda sizin yapmak istediğiniz şeyi yaptım. Hatta thread kullanmak iyidir.Hatta şu an kullanmak istediğim yerde kullanmaktan başka çarem yok.

fatih6761

Alıntı yapılan: yamak - 04 Haziran 2013, 12:15:50
Hocam yazınızı okudum siz orda sleep kullanmayın demişsiniz. Ben sleep kullanımından bahsetmedim zaten.Hatta yazınızda sizin yapmak istediğiniz şeyi yaptım. Hatta thread kullanmak iyidir.Hatta şu an kullanmak istediğim yerde kullanmaktan başka çarem yok.
hocam önceki mesajda yazdığım bayrak olayını deneyin. Bir de mutex lock/unlock ları while dışına almazsanız break çağrısından sonra mutex kilitli kalır. Thread tekrar başlarsa hata alabilirsiniz.

metaltrrocker

Hocam araya girecem ama,programlama dilinde thread  nedir? Ne işe yarar?

yamak

Alıntı yapılan: fatih6761 - 05 Haziran 2013, 00:43:53
hocam önceki mesajda yazdığım bayrak olayını deneyin. Bir de mutex lock/unlock ları while dışına almazsanız break çağrısından sonra mutex kilitli kalır. Thread tekrar başlarsa hata alabilirsiniz.
Hocam cevabınız için teşekkürler dediğiniz yönteme benzer bi yöntemle sorunu hallettim.
Alıntı yapılan: metaltrrocker - 05 Haziran 2013, 01:22:56
Hocam araya girecem ama,programlama dilinde thread  nedir? Ne işe yarar?
Hocam thread'ler türkçede iş parçacıkları olarak adlandırılır.Programlarda paralelliğe benze bir olay oluşturur.Hata çok çekirdekli cpu kullanıyorsanız paralel işlem yaptırmış olursunuz.Bir örnek verecek olursak.Örneğin iki adet fonksiyonum bu iki fonksiyonun birinde dışarıdan veri toplayayım diğerinde ise seri porttan gelen verileri kontrol edeyim.Eğer seri porttan da "dur" mesajı gelirse veri toplama işini bitiriyem.Bu tip durumlarda bir döngü içinde hem veri toplama işini yapıp hem de seri porttan gelen verileri okumak istemiyorsak.Thread lerden faydalanırız.Yani her iki fonksiyonoru muzda aynı anda çalışıyormuş gibi olur.Dediğim gibi eğer çok çekirdekli işlemci kullanıyorsak gerçekten de paralel işlem yaptırmış oluruz.Bir thread için bir çekirdek çalışırken diğer bir thread için diğer çekirdek çalışır.

Bu sayfayı incelersen daha detaylı bilgiye ulaşabilirsin.
http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html

fatih6761

#7
Alıntı yapılan: yamak - 05 Haziran 2013, 02:26:32
Hocam cevabınız için teşekkürler dediğiniz yönteme benzer bi yöntemle sorunu hallettim.Hocam thread'ler türkçede iş parçacıkları olarak adlandırılır.Programlarda paralelliğe benze bir olay oluşturur.Hata çok çekirdekli cpu kullanıyorsanız paralel işlem yaptırmış olursunuz.Bir örnek verecek olursak.Örneğin iki adet fonksiyonum bu iki fonksiyonun birinde dışarıdan veri toplayayım diğerinde ise seri porttan gelen verileri kontrol edeyim.Eğer seri porttan da "dur" mesajı gelirse veri toplama işini bitiriyem.Bu tip durumlarda bir döngü içinde hem veri toplama işini yapıp hem de seri porttan gelen verileri okumak istemiyorsak.Thread lerden faydalanırız.Yani her iki fonksiyonoru muzda aynı anda çalışıyormuş gibi olur.Dediğim gibi eğer çok çekirdekli işlemci kullanıyorsak gerçekten de paralel işlem yaptırmış oluruz.Bir thread için bir çekirdek çalışırken diğer bir thread için diğer çekirdek çalışır.

Bu sayfayı incelersen daha detaylı bilgiye ulaşabilirsin.
http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html
Hocam aslında thread sadece iş parçacığı kısmı. Her program bir process oluyor. Her process'in ise bir main thread'i var. Bu haliyle single process single threaded çalışma biçimi oluyor. Bir process birden fazla thread'i çatallarsa, yani işi aynı anda birden fazla iş parçacığına yaptırırsa single process multithreaded çalışma biçimi olur. Eğer tek çekirdeğiniz varsa pseudo multi threading olur, yani sadece görünüşte paralellik vardır, işletim sisteminin task scheduler'ı bu threadleri single thread sıralı çalıştırır. İki işlemciniz varsa aynı anda iki thread'i çalıştırabilirsiniz.
Tabi burada bellek paylaşımı çok önemli. Örneğin x = x+1 fonksiyonunu for ile 2 kez çalıştırmak istiyorsunuz.
Single thread'de son durumda x = 2 olur. Ancak bellek yönetimine dikkat edilmezse parallelde farklı sonuçlar elde edilir: mesela thread'ler aşağıdaki sırayla çalışırsa:
1.1) Th1 x'i reg'e al.  1.2)Th2 x'i reg'e al.
2.1) Th1 reg'i bir arttır. 2.2) Th2 reg'i bir arttır.
5) Th1 reg'i x'e yaz.
6) Th2 reg'i x'e yaz.
Sonuçta x = 1 olur. Burada threading kütüphaneleri devreye giriyor. OMP'de reduction ayarlarsanız ve x'i shared alana alırsanız yukarıdaki sorun oluşmaz. Ama private(x) yaparsanız x'te hiçbir değişiklik olmaz gibi...
Kolay gelsin hocam, iyi çalışmalar...

metaltrrocker

Açıklamalar için teşekkür ederim.Programlama dilinde thread leri daha önce duymamıştım.Gayet güzel birşeymiş:)
C# da uzmanlaşırsam meyvesini yerim:)
sağolun tekrardan.

fatih6761

Rica ederim. C# da da aynı olaylar var, ancak C# ta paralel işini bu kadar detaya indirmenize gerek yok :)
http://msdn.microsoft.com/en-us/library/dd460693.aspx
Task Parallel library ve linq ile çok daha kolay parallel yazılımlar oluşturabilirsiniz... Kolay gelsin...

Yuunus

"metaltrrocker" thread kullanmak bir nevi cpu multitasking kullanmak gibidir task lari yönetmene izin verir, thread lara öncelik tanırsın ve cpu o uygulamaya yoğunlaşır.

metaltrrocker

Mesela şöyle bir durum varmıdır,x olayı y olayı ile bağlantılı olsun.thread1 olarak x i atayalım,thread2 olarak da y yi.thread ler kendi iclerinde gecikmeye ugramazlarmı? X olayındaki değişkenler y de kullanılıyor diyelim.x e baglı threadler gecikince y yi de etkiler.bu durum olası ve kabul edilebilir bir durum mudur yoksa benmi yanlış düşünüyorum:-)

Yuunus

thread1, thread2 den değişken değeri vs. bekliyorsa elbetteki gecikecektir, istenen bir durummudur bilemem yazdığın programa bağlı.