Autor Wątek: [SDL]Wielokrotne wykorzystanie wątków  (Przeczytany 1346 razy)

Offline Furry

  • Użytkownik
    • DevBlog

# Marzec 23, 2011, 14:01:08
Witam, ostatnio próbuję znaleźć coraz to lepsze sposoby na obsługiwanie wątków. Natrafiłem na pewien problem otóż chciałbym mieć możliwość wykorzystywania tego samego wątku po kilka razy zamiast tworzyć ciągle nowe. Jednak nie za bardzo wiem jak sobie poradzić z tym fantem.
Myślałem nad tym żeby w pętli zrobić samo blokujący się wątek, ale jak wiadomo mutexy nie pozwalają na to żeby w wątek sam siebie blokował.
Poniższy kod przedstawia próbę wymyślenia jakby to miało działać:
class Mutex
{
public:
Mutex();
~Mutex();
void lock();
void unlock();
private:
SDL_mutex *mutex;
};
Mutex::Mutex()
{
mutex=SDL_CreateMutex();

}
Mutex::~Mutex()
{
SDL_DestroyMutex(mutex);
}
void Mutex::lock()
{
SDL_mutexP(mutex);
}
void Mutex::unlock()
{
SDL_mutexV(mutex);
}

Mutex *mutex;
bool working;
int foo(void *data)
{
while(working)
{
mutex->lock();
cout<<"Zwolnione\n";
}
return 0;
}
int main()
{
mutex=new Mutex();
mutex->lock();
SDL_CreateThread(foo, NULL);
char ch='\0';
working=true;
while(ch!='0')
{
ch=getchar();
if(ch=='a')
mutex->unlock();
}
working=false;
delete mutex;
return 0;
}

Pętla while() będzie się oczywiście wykonywać puki working != false , z tym, że myślałem nad tym żeby mutex->lock(); powodował, że po przejściu 1 obiegu pętli mutex sam siebie zablokuje. Sposób niestety nie działa.

Czy ktoś mógłby mi doradzić(albo polecić jakieś materiały) na temat jak powinno się operować wątkami tak by można je było wielokrotnie wykorzystywać?

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline albireo

  • Użytkownik

# Marzec 23, 2011, 17:59:05
Hint: SDL_CondWait, SDL_CondSignal

Offline Furry

  • Użytkownik
    • DevBlog

# Marzec 23, 2011, 21:44:28
W sensie zamiast locka w tym whilu użyć condów i to wystarczy?

Offline hashedone

  • Użytkownik

# Marzec 23, 2011, 22:03:21
Z tego co wiem to żeby założyć conditionala musisz mieć założonego locka (tzn. wait() trzeba wykonać w zablokowanym fragmentu kodu, przy czym ten wait() od razu odblokowuje locka aż do otrzymania signal). Nie wiem jak to jest w SDL, ale ogólnie condvar chyba tak działają.

Offline Kos

  • Użytkownik
    • kos.gd

# Marzec 23, 2011, 22:31:42
Z tego co wiem to żeby założyć conditionala musisz mieć założonego locka (tzn. wait() trzeba wykonać w zablokowanym fragmentu kodu, przy czym ten wait() od razu odblokowuje locka aż do otrzymania signal). Nie wiem jak to jest w SDL, ale ogólnie condvar chyba tak działają.
Tak, przynajmniej w pthreadach (a SDL-owe API jest na nich wzorowane, nie?).

Wydaje mi się też, że gdy wait() się doczeka, to lock znowu będzie zablokowany i trzeba go będzie odblokować (co utrzymuje nam relację 1-1 dla locków). Ktoś potwierdzi?

Offline agent_J

  • Użytkownik

# Marzec 23, 2011, 22:49:28
Mniej więcej tak:

Wątek A: mutex.lock(); cond.wait(&mutex)/timedWait;  --- kod z mutexem zablokowanym mutex.unlock();
Wątek B: mutex.lock(); cond.signal()/broardcast(); mutex.unlock();

Offline Furry

  • Użytkownik
    • DevBlog

# Marzec 23, 2011, 23:10:14
a jak chce zakończyć wątek A(nie killując go)? Bo o ile dobrze pamiętam wątek jest resetowany przez condy?
Jak rozumiem wątek A jest tworzony przez jakiś wątek, a w wątku B jest po prostu wywołanie conda?

Edit:
Sprawdziłem, sposób faktycznie działa:) Wielkie dzięki. Jest tylko 1 uwaga:
mutex.lock(); mutex.unlock(); w B są niepotrzebne
« Ostatnia zmiana: Marzec 23, 2011, 23:28:20 wysłana przez Furry »

Offline agent_J

  • Użytkownik

# Marzec 23, 2011, 23:40:51
Są potrzebne jeśli wątek B modyfikuje dane zabezpieczane przez mutex. Przerywanie wątku można zrobić np. przez:

zmienna klasowa:
bool done = false;

wątek:
mutex.lock();
while(!done)
{
 cond.wait(&mutex);
 if(done)
  break;
}
mutex.unlock();

kod:
mutex.lock();
done = true;
cond.signal();
mutex.unlock();