From: jp2code on 5 Jun 2007 12:33 I want a loop to run in my RUNTIME_CLASS object derived from CWinThread. I can initialize my thread, and I can call portions of my class. But, how do I specify that I want to run a Loop after everything has initialized? I was planning on placing this loop inside the overridden Run method, but the Help says this is rarely done. Should I place my loop somewhere else? That's fine by me, but then how do I call it? If I use PostThreadMessage and having my message handler call the loop function, then the message handler will not return (or process any other messages) until the loop has completed - which will only happen after the thread is complete.
From: Joseph M. Newcomer on 5 Jun 2007 14:14 Wrong approach. If you are running a continuous loop, you don't want a UI thread. If you are running a UI thread, you don't want a continuous loop. The two models are incompatible. Here's a really good heuristic: if you think you need to modify the Run method, you are wrong. If you think real hard about why you need to do it and decide it is the right way, you're still wrong. 99.999% of the time this heuristic give you a correct answer. I think you do not understand threading, asynchronous I/O, or serial I/O well enough to see the architecture. Take a look at my essay on serial port I/O. It is a subset of several solutions I have implemented, but it is closer to an approach than what you have proposed. Note that it uses "pseudo-synchronous" I/O to handle both sides of the communication, but it is essential that you use asynchronous I/O and have separate threads for input and output. You should not have a loop at all. The fact that you think you need a loop of the nature you describe suggest that you really need to understand threading and asynchronous I/O more deeply. Take a look at my essays on UI threads, worker threas, the use of I/O completion ports, and my serial I/O essay; once you have studied those, you may see the correct answer to your question more clearly. joe On Tue, 5 Jun 2007 11:33:11 -0500, "jp2code" <poojo.com/mail> wrote: >I want a loop to run in my RUNTIME_CLASS object derived from CWinThread. > >I can initialize my thread, and I can call portions of my class. > >But, how do I specify that I want to run a Loop after everything has >initialized? > >I was planning on placing this loop inside the overridden Run method, but >the Help says this is rarely done. > >Should I place my loop somewhere else? That's fine by me, but then how do I >call it? > >If I use PostThreadMessage and having my message handler call the loop >function, then the message handler will not return (or process any other >messages) until the loop has completed - which will only happen after the >thread is complete. > Joseph M. Newcomer [MVP] email: newcomer(a)flounder.com Web: http://www.flounder.com MVP Tips: http://www.flounder.com/mvp_tips.htm
From: jp2code on 5 Jun 2007 15:10 I'm reading your essay on worker threads, but I won't be able to impliment asynchronous I/O because we include WinCE / PocketPC devices, and they do not support overlapped operations. Currently, I have a main thread for writing, a worker thread for reading, and a global BOOL value called (ironically) g_Overlapped. Here is how I use it: Main Thread - Writing: while (g_Overlapped) Sleep(1); g_Overlapped = TRUE; g_Overlapped = WriteFile( ... ); if (g_Overlapped) { g_Overlapped = FALSE; // code to process } Worker Thread - Reading: while (g_Overlapped) Sleep(1); g_Overlapped = TRUE; g_Overlapped = ReadFile( ... ); if (g_Overlapped) { g_Overlapped = FALSE; // code to process } This should work, wouldn't you think?
From: Scott McPhillips [MVP] on 5 Jun 2007 21:02 jp2code wrote: > I'm reading your essay on worker threads, but I won't be able to impliment > asynchronous I/O because we include WinCE / PocketPC devices, and they do > not support overlapped operations. > > Currently, I have a main thread for writing, a worker thread for reading, > and a global BOOL value called (ironically) g_Overlapped. > > Here is how I use it: > > Main Thread - Writing: > while (g_Overlapped) > Sleep(1); > g_Overlapped = TRUE; > g_Overlapped = WriteFile( ... ); > if (g_Overlapped) > { > g_Overlapped = FALSE; > // code to process > } > > Worker Thread - Reading: > while (g_Overlapped) > Sleep(1); > g_Overlapped = TRUE; > g_Overlapped = ReadFile( ... ); > if (g_Overlapped) > { > g_Overlapped = FALSE; > // code to process > } > > This should work, wouldn't you think? No. You don't understand the race conditions that are inherent in multithreading. You cannot test the flag and then assume that it is unchanged in the next instruction. Synchronization primitives are necessary: You can't do it with if, while, etc. You need to stop coding and work on the design. (Or find some experienced help.) -- Scott McPhillips [MVP VC++]
From: Joseph M. Newcomer on 6 Jun 2007 02:31 See below... On Tue, 5 Jun 2007 14:10:53 -0500, "jp2code" <poojo.com/mail> wrote: >I'm reading your essay on worker threads, but I won't be able to impliment >asynchronous I/O because we include WinCE / PocketPC devices, and they do >not support overlapped operations. > >Currently, I have a main thread for writing, a worker thread for reading, >and a global BOOL value called (ironically) g_Overlapped. > >Here is how I use it: > >Main Thread - Writing: > while (g_Overlapped) > Sleep(1); **** This is REALLY BAD. WaitForSingleObject(g_Overlapped); might make sense, but one thing that is a near-certainty: if you have to put a Sleep() call in a thread to make it work, the design is wrong. After reading this a second time, I am convinced that this is an incorrect attempt to provide mutual exclusion. Consider what happens if g_Overlapped is set FALSE. The upper thread drops down and tries to set g_Overlapped to TRUE. But right before the store instruction that moves TRUE to g_Overlapped,the scheduler says "end of your timeslice". It then dispatches the lower thread. The lower thread was about to do the load of g_Overlapped when it was suspended. So it loads FALSE, discovers that it, too, can do a Write, and now both threads are trying to access the serial port at the same time. Nothing but a total rewrite can save this code. It is a time bomb waiting to happen, and eventually it WILL blow up. That is guaranteed beyond any shadow of doubt. It is not a question of 'if' but merely 'when'. The probability that it will fail some time in the future is exactly 100%. ***** > g_Overlapped = TRUE; **** So why is it being set above and then reassigned below? [Never mind, I see in the second reading that this is just flat-out wrong programming and will have to be rewritten] **** > g_Overlapped = WriteFile( ... ); > if (g_Overlapped) > { > g_Overlapped = FALSE; **** Every use of g_Overlapped is erroneous code. **** > // code to process > } > >Worker Thread - Reading: > while (g_Overlapped) > Sleep(1); **** This is even more confusing. Why are two threads testing the same variable and taking actions that set and reset it? This looks frighteningly like some bizarre attempt to get mutual exclusion without using any mutual exclusion primitive, which is beyond any shadow of doubt a total flaming disaster and absolutely MUST be redone! [pass 2] it IS a total flaming disaster. **** > g_Overlapped = TRUE; > g_Overlapped = ReadFile( ... ); > if (g_Overlapped) > { > g_Overlapped = FALSE; > // code to process > } > >This should work, wouldn't you think? **** Actually, I would be amazed if it could possibly work. Secondly, if it does work, it is horrendously inefficient. I don't even know if CE *can* sleep for 1ms (as opposed to 10 or 15 or some other value) but in any case, polling is not synchronization, and polling non-synchronized variables is simply flat-out completely wrong and any illusion that it works is miraculous. If you want mutual exclusion, you MUST use a mutex or CRITICAL_SECTION. There are zero other choices. joe > Joseph M. Newcomer [MVP] email: newcomer(a)flounder.com Web: http://www.flounder.com MVP Tips: http://www.flounder.com/mvp_tips.htm
|
Next
|
Last
Pages: 1 2 Prev: CTreeCtrl::SelectItem() behaves weird on VISTA Next: VS2005/Vista issues |