🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Threads and buffers

Started by
3 comments, last by wrathgame 22 years, 10 months ago
Hiya all, Just a quick question.. im still relativly new to threads and i was wondering.. I have a thread which recieves data into a buffer. I then want the main thread to read that data out and remove the data from the queue my question is how do i tell the main thread to read the buffer ?? the only thing i can really think of is sending a message sendMessage() to the apps hwnd which when it recieves it then acuires a critical section and reads the buffer and de-queues it. please let me know if thats the correct way or if there is a better way ;-) Thanks -Tim
~ Tim
Advertisement
Well, if you declare your buffer as global - you can read it from any thread. Just make sure to lock it first (with critial section or otherwise).

Cheers!
Meduzza
<>

yeh i know ;-) but how do i tell another thread that i want it to read from the buffer because it has data in it.. i dont want to poll or Wait for an event because the thread needs to do other stuff untill the data arrives

Tim
~ Tim
One really easy way to do this is to use a simple variable flag. In your thread''s processing loop you just test if the flag is set. If it is, read from the buffer.

Another, more interesting way, is to use QueueUserAPC. It allows you to specify a function, target thread, and context data.

  // C-style data structuretypedef struct tagMyData{    CRITICAL_SECTION cs_;    char*            buffer_;    int              len_;} MyData, *MyDataPtr;VOID CALLBACK YourAPCProc(ULONG_PTR dwParam){    // do something with dwParam}DWORD WINAPI Thread1(void* parameter)// or main()/WinMain(){    while(!shutdown)    {        // main code somewhere - Thread 1        QueueUserAPC(YourAPCProc, Thread2sHandle, AnyDataPtr);        // move on    }}DWORD WINAPI Thread2(void* parameter){    while(!shutdown)    {        // do some processing        SleepEx(0, TRUE);    }}  


The call to SleepEx is necessary to cause the thread to relinquish its remain timeslice. This allows APC calls in the threads queue to be called. This is called having the thread in an alertable state.

This might be overkill for what you want to do but it works.

BTW:

A C++ way to do this might be:

  class queued_cmd{    public:        virtual ~queued_cmd();        virtual void operator () = 0;};class my_cmd : public queued_cmd{    public:        mycmd(/*params*/);        virtual ~mycmd();        virtual void operator();    private:        // data};VOID CALLBACK UserAPC(ULONG_PTR data){    queued_cmd* cmd = (queued_cmd*)data;    cmd();}// etc  


Hopefully this answered your question Wrathgame.
I can''t remember if calling SleepEx causes a transition from user-mode to kernel mode. That kind of transition can eat about 1000 CPU cycles. All the WaitFor... functions do this and so do the threads that try to enter critical sections but fail. That is why on multiprocessor systems it is sometimes good to perform what they call a spin-lock. To do this, you initialize your critical section by calling InitializeCriticalSectionAndSpinCount . Then, everytime you call EnterCritical section, if they thread can''t acquire it, it spins for a specified number of times. If the critical section becomes available the thread doesn''t have to be suspended (put into a wait state). This is very good for multiprocessor systems as it has to do with cache lines etc.

Best regards,





Dire Wolf
www.digitalfiends.com
[email=direwolf@digitalfiends.com]Dire Wolf[/email]
www.digitalfiends.com
Thanks again dire :-)

I have added that QueueUserAPC code into my code.. it tells the accept thread to setup a new accept socket :-) i was using a event and that thread was doing a WaitForMultipleObjects and waiting for either a shutdown or a setup a new socket message.

and btw i did this
SleepEx(INFINITE, TRUE);

note infinite = -1 (i think)

so that it doesnt keep having to call SleepEx ;-) because it will be interrupted when it recieves an APC and that thread is purly for that one task

the only prob i had was i cant use it for the purpose i wanted to :-/ because i cant see ho i can get the thread handle for my main thread (the thread i want to call)

Thanks

Tim
~ Tim

This topic is closed to new replies.

Advertisement