Is a Thread appropriate?

Hi,

I'm working on a dialog based app that utilizes PC's serial port. Up to now, 
the app is just capable  to send.  I'd like to extend it by receive 
functionality. Actually, port I/O isn't the issue since I'm using a dll that 
does it for me.  The issue I discovered is that I would lock my application 
for user commands while waiting for some data to be received.  Data arrives 
now and then - might be within a second or might take longer like 5 minites 
....

 I applied a thread to workaround the locking of the application. But I 
don't know if that is an appropriate technique solve this kind of 
communication. I think it would be much better if my app gets notified  by 
incomming data and only in this case the application reads from the port.  
Does anyone have some suggestions? Whats appropriate for that?

Here's what I did:

- there's a port.dll that I'm interfacing thru a wrapper class CSerialCom
- CSerialCom got member functions for open, close, send and read port 

here's the member function that i use for reading from port in particular:

int CSerialCom::ReadByte()
{
typedef int (CALLBACK* LP2INT)();
char szFuncName[9] = "READBYTE";
LP2INT p;
p = (LP2INT)GetProcAddress(hDLL, szFuncName);
    return p();

}


The following code is a snippet of my dialog based app where I create the 
worker thread:
....
CWinThread* pThread = AfxBeginThread(threadHelperFunc, this);
pThread->SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
....

// static function
UINT CDspComDlg::threadHelperFunc(LPVOID pParam)
{
CDspComDlg* pApp = (CDspComDlg*) pParam;
if (pApp)
{
  pApp->threadReceive();
  return 1;
}

return 0;
}



void CDspComDlg::threadReceive(void)
{
	chBuffer = pCom->ReadByte();                     // pCom is object of 
CSerialCom
	if (bFirstByte)							// lower byte to be expected?
	{

		if (LowerByte != chBuffer)			// new data has been received
		{
			LowerByte = chBuffer;
			bFirstByte = false;				// set flag, upper byte to be expected next
		}
	}
	else
	{
		// we expect upper byte
		if (UpperByte != chBuffer)
		{
			UpperByte = chBuffer;			// received data complete
			bFirstByte = true;				// next will be lower byte
			
			// alignment
			ReceivedValue = (short int)UpperByte;
			ReceivedValue = ReceivedValue <<8;
			ReceivedValue += (short int)LowerByte; 
                 
                       ...
                       etc.
                       ....
		}
	}
	Sleep(1);
}


Thanks & Regards,

Arno
0
2/17/2005 6:51:02 PM
vc.mfc 33608 articles. 0 followers. Follow

10 Replies
606 Views

Similar Articles

[PageSpeed] 20

I thread is a good solution for this problem.  I have one suggestion, you
should try to post a message to the Application thread that data is
avaliable instead of calling function directly, but other than that you are
on the right track.

AliR.

"Arno Kromke" <ArnoKromke@discussions.microsoft.com> wrote in message
news:DEDADC5C-426E-4131-A205-6114B5AC772C@microsoft.com...
> Hi,
>
> I'm working on a dialog based app that utilizes PC's serial port. Up to
now,
> the app is just capable  to send.  I'd like to extend it by receive
> functionality. Actually, port I/O isn't the issue since I'm using a dll
that
> does it for me.  The issue I discovered is that I would lock my
application
> for user commands while waiting for some data to be received.  Data
arrives
> now and then - might be within a second or might take longer like 5
minites
> ...
>
>  I applied a thread to workaround the locking of the application. But I
> don't know if that is an appropriate technique solve this kind of
> communication. I think it would be much better if my app gets notified  by
> incomming data and only in this case the application reads from the port.
> Does anyone have some suggestions? Whats appropriate for that?
>
> Here's what I did:
>
> - there's a port.dll that I'm interfacing thru a wrapper class CSerialCom
> - CSerialCom got member functions for open, close, send and read port
>
> here's the member function that i use for reading from port in particular:
>
> int CSerialCom::ReadByte()
> {
> typedef int (CALLBACK* LP2INT)();
> char szFuncName[9] = "READBYTE";
> LP2INT p;
> p = (LP2INT)GetProcAddress(hDLL, szFuncName);
>     return p();
>
> }
>
>
> The following code is a snippet of my dialog based app where I create the
> worker thread:
> ...
> CWinThread* pThread = AfxBeginThread(threadHelperFunc, this);
> pThread->SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
> ...
>
> // static function
> UINT CDspComDlg::threadHelperFunc(LPVOID pParam)
> {
> CDspComDlg* pApp = (CDspComDlg*) pParam;
> if (pApp)
> {
>   pApp->threadReceive();
>   return 1;
> }
>
> return 0;
> }
>
>
>
> void CDspComDlg::threadReceive(void)
> {
> chBuffer = pCom->ReadByte();                     // pCom is object of
> CSerialCom
> if (bFirstByte) // lower byte to be expected?
> {
>
> if (LowerByte != chBuffer) // new data has been received
> {
> LowerByte = chBuffer;
> bFirstByte = false; // set flag, upper byte to be expected next
> }
> }
> else
> {
> // we expect upper byte
> if (UpperByte != chBuffer)
> {
> UpperByte = chBuffer; // received data complete
> bFirstByte = true; // next will be lower byte
>
> // alignment
> ReceivedValue = (short int)UpperByte;
> ReceivedValue = ReceivedValue <<8;
> ReceivedValue += (short int)LowerByte;
>
>                        ...
>                        etc.
>                        ....
> }
> }
> Sleep(1);
> }
>
>
> Thanks & Regards,
>
> Arno


0
AliR1 (391)
2/17/2005 7:26:30 PM
Arno Kromke wrote:
> Hi,
> 
> I'm working on a dialog based app that utilizes PC's serial port. Up to now, 
> the app is just capable  to send.  I'd like to extend it by receive 
> functionality. Actually, port I/O isn't the issue since I'm using a dll that 
> does it for me.  The issue I discovered is that I would lock my application 
> for user commands while waiting for some data to be received.  Data arrives 
> now and then - might be within a second or might take longer like 5 minites 
> ...
> 
>  I applied a thread to workaround the locking of the application. But I 
> don't know if that is an appropriate technique solve this kind of 
> communication. I think it would be much better if my app gets notified  by 
> incomming data and only in this case the application reads from the port.  
> Does anyone have some suggestions? Whats appropriate for that?

The thread is not only appropriate, it is necessary to solve this kind 
of problem.  The serial port does not provide any mechanism to notify a 
GUI thread when data is available.  The best approach is to use the 
thread to provide this mechanism for yourself.

Instead of having your thread exit after every call you should change it 
to consist of a loop that waits for data to arrive.  When data does 
arrive the thread can post it to the GUI with PostMessage.  The call to 
the ReadFile API will suspend the thread efficiently until data is received.

Hint: Also initialize with SetCommTimeouts so ReadFile will return 
periodically when there is no data.  This will let you gracefully shut 
down your thread when the application is closing.

-- 
Scott McPhillips [VC++ MVP]

0
Scott
2/17/2005 8:31:05 PM
So, I should rather implement the thread to CSerialCom than into the dlg 
class? The main application thread gets notified by PostMessage. 

I'm new to Threads. How does my main thread obtain the posted message? Is it 
done by the message map? I also found PostThreadMessage, what suits better?

Arno
0
2/17/2005 9:17:06 PM
A thread is a good solution here.

You also need to implement a way to close down the thread cleanly, if the
user shuts down the application while it's running/waiting for data on the
serial port.

Mike


"Arno Kromke" <ArnoKromke@discussions.microsoft.com> wrote in message
news:DEDADC5C-426E-4131-A205-6114B5AC772C@microsoft.com...
> Hi,
>
> I'm working on a dialog based app that utilizes PC's serial port. Up to
now,
> the app is just capable  to send.  I'd like to extend it by receive
> functionality. Actually, port I/O isn't the issue since I'm using a dll
that
> does it for me.  The issue I discovered is that I would lock my
application
> for user commands while waiting for some data to be received.  Data
arrives
> now and then - might be within a second or might take longer like 5
minites
> ...
>
>  I applied a thread to workaround the locking of the application. But I
> don't know if that is an appropriate technique solve this kind of
> communication. I think it would be much better if my app gets notified  by
> incomming data and only in this case the application reads from the port.
> Does anyone have some suggestions? Whats appropriate for that?
>
> Here's what I did:
>
> - there's a port.dll that I'm interfacing thru a wrapper class CSerialCom
> - CSerialCom got member functions for open, close, send and read port
>
> here's the member function that i use for reading from port in particular:
>
> int CSerialCom::ReadByte()
> {
> typedef int (CALLBACK* LP2INT)();
> char szFuncName[9] = "READBYTE";
> LP2INT p;
> p = (LP2INT)GetProcAddress(hDLL, szFuncName);
>     return p();
>
> }
>
>
> The following code is a snippet of my dialog based app where I create the
> worker thread:
> ...
> CWinThread* pThread = AfxBeginThread(threadHelperFunc, this);
> pThread->SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
> ...
>
> // static function
> UINT CDspComDlg::threadHelperFunc(LPVOID pParam)
> {
> CDspComDlg* pApp = (CDspComDlg*) pParam;
> if (pApp)
> {
>   pApp->threadReceive();
>   return 1;
> }
>
> return 0;
> }
>
>
>
> void CDspComDlg::threadReceive(void)
> {
> chBuffer = pCom->ReadByte();                     // pCom is object of
> CSerialCom
> if (bFirstByte) // lower byte to be expected?
> {
>
> if (LowerByte != chBuffer) // new data has been received
> {
> LowerByte = chBuffer;
> bFirstByte = false; // set flag, upper byte to be expected next
> }
> }
> else
> {
> // we expect upper byte
> if (UpperByte != chBuffer)
> {
> UpperByte = chBuffer; // received data complete
> bFirstByte = true; // next will be lower byte
>
> // alignment
> ReceivedValue = (short int)UpperByte;
> ReceivedValue = ReceivedValue <<8;
> ReceivedValue += (short int)LowerByte;
>
>                        ...
>                        etc.
>                        ....
> }
> }
> Sleep(1);
> }
>
>
> Thanks & Regards,
>
> Arno


0
2/17/2005 9:23:33 PM
Arno Kromke wrote:
> So, I should rather implement the thread to CSerialCom than into the dlg 
> class? The main application thread gets notified by PostMessage. 
> 
> I'm new to Threads. How does my main thread obtain the posted message? Is it 
> done by the message map? I also found PostThreadMessage, what suits better?
> 
> Arno

Yes, if your dialog makes a blocking call to read the com port then the 
dialog GUI stops working until the call returns.  That is why the serial 
port should be called from a separate thread.

You must use PostMessage when posting to the GUI thread.  For an example 
of interthread messaging see http://www.mvps.org/vcfaq/mfc/12.htm

-- 
Scott McPhillips [VC++ MVP]

0
Scott
2/17/2005 11:11:17 PM
Here is a couple good links for Threads

http://bobmoore.mvps.org/Win32/w32tip31.htm
http://www.murrayc.com/learning/windows/multithreading.shtml


Good Luck,
-- 
Christopher J. Holland [!MVP]
http://www.mvps.org/vcfaq/
http://www.codeguru.com
http://www.codeproject.com
http://www.naughter.com/
http://support.microsoft.com/default.aspx
http://msdn.microsoft.com/howto/
http://msdn.microsoft.com/library/
www.flounder.com/mvp_tips.htm

"Arno Kromke" <ArnoKromke@discussions.microsoft.com> wrote in message 
news:DEDADC5C-426E-4131-A205-6114B5AC772C@microsoft.com...
> Hi,
>
> I'm working on a dialog based app that utilizes PC's serial port. Up to 
> now,
> the app is just capable  to send.  I'd like to extend it by receive
> functionality. Actually, port I/O isn't the issue since I'm using a dll 
> that
> does it for me.  The issue I discovered is that I would lock my 
> application
> for user commands while waiting for some data to be received.  Data 
> arrives
> now and then - might be within a second or might take longer like 5 
> minites
> ...
>
> I applied a thread to workaround the locking of the application. But I
> don't know if that is an appropriate technique solve this kind of
> communication. I think it would be much better if my app gets notified  by
> incomming data and only in this case the application reads from the port.
> Does anyone have some suggestions? Whats appropriate for that?
>
> Here's what I did:
>
> - there's a port.dll that I'm interfacing thru a wrapper class CSerialCom
> - CSerialCom got member functions for open, close, send and read port
>
> here's the member function that i use for reading from port in particular:
>
> int CSerialCom::ReadByte()
> {
> typedef int (CALLBACK* LP2INT)();
> char szFuncName[9] = "READBYTE";
> LP2INT p;
> p = (LP2INT)GetProcAddress(hDLL, szFuncName);
>    return p();
>
> }
>
>
> The following code is a snippet of my dialog based app where I create the
> worker thread:
> ...
> CWinThread* pThread = AfxBeginThread(threadHelperFunc, this);
> pThread->SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
> ...
>
> // static function
> UINT CDspComDlg::threadHelperFunc(LPVOID pParam)
> {
> CDspComDlg* pApp = (CDspComDlg*) pParam;
> if (pApp)
> {
>  pApp->threadReceive();
>  return 1;
> }
>
> return 0;
> }
>
>
>
> void CDspComDlg::threadReceive(void)
> {
> chBuffer = pCom->ReadByte();                     // pCom is object of
> CSerialCom
> if (bFirstByte) // lower byte to be expected?
> {
>
> if (LowerByte != chBuffer) // new data has been received
> {
> LowerByte = chBuffer;
> bFirstByte = false; // set flag, upper byte to be expected next
> }
> }
> else
> {
> // we expect upper byte
> if (UpperByte != chBuffer)
> {
> UpperByte = chBuffer; // received data complete
> bFirstByte = true; // next will be lower byte
>
> // alignment
> ReceivedValue = (short int)UpperByte;
> ReceivedValue = ReceivedValue <<8;
> ReceivedValue += (short int)LowerByte;
>
>                       ...
>                       etc.
>                       ....
> }
> }
> Sleep(1);
> }
>
>
> Thanks & Regards,
>
> Arno 


0
msnews (126)
2/18/2005 3:05:48 AM
Yes. A thread is both appropriate and necessary.

Now, if you are not doing dynamic loading of the DLL, you shouldn't need GetProcAddress.
If you are doing dynamic loading, get the address exactly once, when you load the DLL, not
every time you call the function. Assume that the lookup of the name is very, very,
expensive.

Note that it is foolish to create a char array, particularly a char array of a fixed size.
GetProcAddress would work fine as

	p = (LP2INT)GetProcAddress(hDLL, "READBYTE");
so why do you think you need to declare a separate variable for this purpose?

If you need to declare a separate variable (which is inappropriate here), you could
declare it as

const char szFuncName[] = "READBYTE";

but there is no reason to create the array at all; you could have done

const char * szFuncName = "READBYTE";

but neither of these make much sense in this particular context. Why introduce a
completely unnecessary separate variable to solve a nonexistent problem?

If you want to do both input and output concurrently, you need to use asynchronous I/O;
presumably your DLL is doing this (although the use of a DLL to do a trivial task is
already suspect. Asynchrnonous serial I/O is relatively trivial to write in such a case).

I tend to use two threads: one for input, and one for output. Then if the ReadFile fails
on an ERROR_IO_PENDING I do a WaitForMultipleObjects on the event handle and a shutdown
event, where the shutdown event is the [0]th element of the array. This allows for
graceful shutdown. This allows you to set longer timeouts and get better response to
thread shutdown requests.

What I don't understand is why you are creating a thread each time you read a character.
This is horrendously inefficient. There is no need to do this.

There is no need to test pParam as you have done. It is simply an error to pass in a NULL,
so you should do

ASSERT(pParam != NULL)
 
if(pParam == NULL)
     return 0;

Forget return values other than 0; nobody cares about thread return values.

For more, see below...

On Thu, 17 Feb 2005 10:51:02 -0800, "Arno Kromke" <ArnoKromke@discussions.microsoft.com>
wrote:

>Hi,
>
>I'm working on a dialog based app that utilizes PC's serial port. Up to now, 
>the app is just capable  to send.  I'd like to extend it by receive 
>functionality. Actually, port I/O isn't the issue since I'm using a dll that 
>does it for me.  The issue I discovered is that I would lock my application 
>for user commands while waiting for some data to be received.  Data arrives 
>now and then - might be within a second or might take longer like 5 minites 
>...
>
> I applied a thread to workaround the locking of the application. But I 
>don't know if that is an appropriate technique solve this kind of 
>communication. I think it would be much better if my app gets notified  by 
>incomming data and only in this case the application reads from the port.  
>Does anyone have some suggestions? Whats appropriate for that?
>
>Here's what I did:
>
>- there's a port.dll that I'm interfacing thru a wrapper class CSerialCom
>- CSerialCom got member functions for open, close, send and read port 
>
>here's the member function that i use for reading from port in particular:
>
>int CSerialCom::ReadByte()
>{
>typedef int (CALLBACK* LP2INT)();
>char szFuncName[9] = "READBYTE";
>LP2INT p;
>p = (LP2INT)GetProcAddress(hDLL, szFuncName);
>    return p();
>
>}
>
>
>The following code is a snippet of my dialog based app where I create the 
>worker thread:
>...
>CWinThread* pThread = AfxBeginThread(threadHelperFunc, this);
>pThread->SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
>...
>
>// static function
>UINT CDspComDlg::threadHelperFunc(LPVOID pParam)
>{
>CDspComDlg* pApp = (CDspComDlg*) pParam;
>if (pApp)
>{
>  pApp->threadReceive();
>  return 1;
>}
>
>return 0;
>}
>
>
>
>void CDspComDlg::threadReceive(void)
>{
>	chBuffer = pCom->ReadByte();                     // pCom is object of 
>CSerialCom
>	if (bFirstByte)							// lower byte to be expected?
>	{
>
>		if (LowerByte != chBuffer)			// new data has been received
>		{
>			LowerByte = chBuffer;
>			bFirstByte = false;				// set flag, upper byte to be expected next
>		}
>	}
>	else
>	{
>		// we expect upper byte
>		if (UpperByte != chBuffer)
>		{
>			UpperByte = chBuffer;			// received data complete
>			bFirstByte = true;				// next will be lower byte
>			
>			// alignment
>			ReceivedValue = (short int)UpperByte;
>			ReceivedValue = ReceivedValue <<8;
>			ReceivedValue += (short int)LowerByte; 
>                 
>                       ...
>                       etc.
>                       ....
>		}
>	}
>	Sleep(1);
>}
>
>
This is about the most convoluted code I could imagine to accomplish a simple task. 

The code is incredibly simple:

chBuffer[0] = pCom->ReadByte();
chBuffer[1] = pCom->ReadByte();
ReceivedValue = *(short int *) chBuffer;

I have no idea why you have chosen to create the received value in such a complex fashion.
	ReceivedValue = MAKEWORD(lowerByte, upperByte);

would have done the job without any complexity, but the whole business about trying to
figure out what byte you are reading and where to put it is needlessly complex.

Lose the Sleep(1). If your program doesn't work without it, you have such deep and
fundamental flaws that it isn't going to save you. 

Note that this code (both yours and mine) doesn't recover from serial port I/O errors.
Presumably they throw an exception; otherwise, you have to assume that the I/O completed.
In the case of trying to do asynchronous shutdown, this won't work very well. If you are
doing syncrhonous I/O, you are in seirously deep trouble anyway (you can't do concurrent
I/O, you can't shut down your program), so it is reasonably safe to assume that
asynchronous I/O is mandatory.

If the DLL isn't doing asynchronous I/O, scrap it. I posted the code for async I/O within
the last day on this newsgroup. 
				joe
>Thanks & Regards,
>
>Arno

Joseph M. Newcomer [MVP]
email: newcomer@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
0
newcomer (15975)
2/18/2005 6:07:00 AM
Thanks for the links, I'll read the content carefully.

Arno



"Christopher J. Holland.................." wrote:

> Here is a couple good links for Threads
> 
> http://bobmoore.mvps.org/Win32/w32tip31.htm
> http://www.murrayc.com/learning/windows/multithreading.shtml
> 
> 
> Good Luck,
> -- 
> Christopher J. Holland [!MVP]
> http://www.mvps.org/vcfaq/
> http://www.codeguru.com
> http://www.codeproject.com
> http://www.naughter.com/
> http://support.microsoft.com/default.aspx
> http://msdn.microsoft.com/howto/
> http://msdn.microsoft.com/library/
> www.flounder.com/mvp_tips.htm

0
2/18/2005 8:03:09 AM

"Joseph M. Newcomer" wrote:

> Yes. A thread is both appropriate and necessary.
> 
> Now, if you are not doing dynamic loading of the DLL, you shouldn't need GetProcAddress.
> If you are doing dynamic loading, get the address exactly once, when you load the DLL, not
> every time you call the function. Assume that the lookup of the name is very, very,
> expensive.

Actually, I'm not responsible for the CSerialCom. However I used it without 
trying to understand ...
Why is it bad to GetProcAddress every time? It takes much time to evaluate 
the address? Therefore it's better to store the result, right?

> 
> Note that it is foolish to create a char array, particularly a char array of a fixed size.
> GetProcAddress would work fine as
> 
> 	p = (LP2INT)GetProcAddress(hDLL, "READBYTE");
> so why do you think you need to declare a separate variable for this purpose?
> 
> If you need to declare a separate variable (which is inappropriate here), you could
> declare it as
> 
> const char szFuncName[] = "READBYTE";
> 
> but there is no reason to create the array at all; you could have done
> 
> const char * szFuncName = "READBYTE";
> 
> but neither of these make much sense in this particular context. Why introduce a
> completely unnecessary separate variable to solve a nonexistent problem?
> 
Well, I'm not sure about that. The "READBYTE" has to be stored somewhere. If 
it isn't explicitly linked to a variable, the compiler will assign it to a 
place in memory. Moreover, change the array to a constant (const) doesn't 
change anything, does it? It's then just a constant and can't be changed 
contentwise. Besides the fact that memory is allocated everytime the function 
is called, why don't you like the array? 

char szFuncName[9] = "READBYTE"; 
char *szFuncName = "READBYTE";

Isn't it the same? 

> If you want to do both input and output concurrently, you need to use asynchronous I/O;
> presumably your DLL is doing this (although the use of a DLL to do a trivial task is
> already suspect. Asynchrnonous serial I/O is relatively trivial to write in such a case).
> 
> I tend to use two threads: one for input, and one for output. Then if the ReadFile fails
> on an ERROR_IO_PENDING I do a WaitForMultipleObjects on the event handle and a shutdown
> event, where the shutdown event is the [0]th element of the array. This allows for
> graceful shutdown. This allows you to set longer timeouts and get better response to
> thread shutdown requests.
> 
It is is a small project for my studies and I don't wanted to spend too much 
time on it. I'm not an expert either.  I/O seems to me pretty complex. It's 
the first time that I'm using a thread and I just read a chapter in book 
about it.  I don't have any practial experience on it.

first it looked like:

bool bThreadRunning = true;

void CClass::Run()
{
     while(bThreadRunning)
    {
      ..........
     }

}

void CClass::Stop()
{
   bThreadRunning = false;          // stop thread
}


The problem with that is the CPU load. I had to change it somehow ...


> What I don't understand is why you are creating a thread each time you read a character.
> This is horrendously inefficient. There is no need to do this.
> 
> There is no need to test pParam as you have done. It is simply an error to pass in a NULL,
> so you should do
> 
> ASSERT(pParam != NULL)
>  
> if(pParam == NULL)
>      return 0;
> 
> Forget return values other than 0; nobody cares about thread return values.
> 
ok, thanks

> For more, see below...
> 
> On Thu, 17 Feb 2005 10:51:02 -0800, "Arno Kromke" <ArnoKromke@discussions.microsoft.com>
> wrote:
> 
> >Hi,
> >
> >I'm working on a dialog based app that utilizes PC's serial port. Up to now, 
> >the app is just capable  to send.  I'd like to extend it by receive 
> >functionality. Actually, port I/O isn't the issue since I'm using a dll that 
> >does it for me.  The issue I discovered is that I would lock my application 
> >for user commands while waiting for some data to be received.  Data arrives 
> >now and then - might be within a second or might take longer like 5 minites 
> >...
> >
> > I applied a thread to workaround the locking of the application. But I 
> >don't know if that is an appropriate technique solve this kind of 
> >communication. I think it would be much better if my app gets notified  by 
> >incomming data and only in this case the application reads from the port.  
> >Does anyone have some suggestions? Whats appropriate for that?
> >
> >Here's what I did:
> >
> >- there's a port.dll that I'm interfacing thru a wrapper class CSerialCom
> >- CSerialCom got member functions for open, close, send and read port 
> >
> >here's the member function that i use for reading from port in particular:
> >
> >int CSerialCom::ReadByte()
> >{
> >typedef int (CALLBACK* LP2INT)();
> >char szFuncName[9] = "READBYTE";
> >LP2INT p;
> >p = (LP2INT)GetProcAddress(hDLL, szFuncName);
> >    return p();
> >
> >}
> >
> >
> >The following code is a snippet of my dialog based app where I create the 
> >worker thread:
> >...
> >CWinThread* pThread = AfxBeginThread(threadHelperFunc, this);
> >pThread->SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
> >...
> >
> >// static function
> >UINT CDspComDlg::threadHelperFunc(LPVOID pParam)
> >{
> >CDspComDlg* pApp = (CDspComDlg*) pParam;
> >if (pApp)
> >{
> >  pApp->threadReceive();
> >  return 1;
> >}
> >
> >return 0;
> >}
> >
> >
> >
> >void CDspComDlg::threadReceive(void)
> >{
> >	chBuffer = pCom->ReadByte();                     // pCom is object of 
> >CSerialCom
> >	if (bFirstByte)							// lower byte to be expected?
> >	{
> >
> >		if (LowerByte != chBuffer)			// new data has been received
> >		{
> >			LowerByte = chBuffer;
> >			bFirstByte = false;				// set flag, upper byte to be expected next
> >		}
> >	}
> >	else
> >	{
> >		// we expect upper byte
> >		if (UpperByte != chBuffer)
> >		{
> >			UpperByte = chBuffer;			// received data complete
> >			bFirstByte = true;				// next will be lower byte
> >			
> >			// alignment
> >			ReceivedValue = (short int)UpperByte;
> >			ReceivedValue = ReceivedValue <<8;
> >			ReceivedValue += (short int)LowerByte; 
> >                 
> >                       ...
> >                       etc.
> >                       ....
> >		}
> >	}
> >	Sleep(1);
> >}
> >
> >
> This is about the most convoluted code I could imagine to accomplish a simple task. 
> 
> The code is incredibly simple:
> 
> chBuffer[0] = pCom->ReadByte();
> chBuffer[1] = pCom->ReadByte();
> ReceivedValue = *(short int *) chBuffer;
> 
> I have no idea why you have chosen to create the received value in such a complex fashion.
> 	ReceivedValue = MAKEWORD(lowerByte, upperByte);

I like your solution better ;-) very efficient in comparison to what I've 
done. 

> 
> would have done the job without any complexity, but the whole business about trying to
> figure out what byte you are reading and where to put it is needlessly complex.
> 
> Lose the Sleep(1). If your program doesn't work without it, you have such deep and
> fundamental flaws that it isn't going to save you. 
> 

I think I can get rid of it. But what's wrong with Sleep? It's like a wait 
for the working thread and returns computation time to the main thread.

> Note that this code (both yours and mine) doesn't recover from serial port I/O errors.
> Presumably they throw an exception; otherwise, you have to assume that the I/O completed.
> In the case of trying to do asynchronous shutdown, this won't work very well. If you are
> doing syncrhonous I/O, you are in seirously deep trouble anyway (you can't do concurrent
> I/O, you can't shut down your program), so it is reasonably safe to assume that
> asynchronous I/O is mandatory.
> 
> If the DLL isn't doing asynchronous I/O, scrap it. I posted the code for async I/O within
> the last day on this newsgroup. 
> 				joe

Ok, I'll have a look at your i/o code. Thanks reviewing my code and for all 
of your
suggestions and qualified critics.
 
> >Thanks & Regards,
> >
> >Arno
> 
> Joseph M. Newcomer [MVP]
> email: newcomer@flounder.com
> Web: http://www.flounder.com
> MVP Tips: http://www.flounder.com/mvp_tips.htm
> 

Arno
0
2/18/2005 8:59:03 AM
See below...
On Fri, 18 Feb 2005 00:59:03 -0800, "Arno Kromke" <ArnoKromke@discussions.microsoft.com>
wrote:

>
>
>"Joseph M. Newcomer" wrote:
>
>> Yes. A thread is both appropriate and necessary.
>> 
>> Now, if you are not doing dynamic loading of the DLL, you shouldn't need GetProcAddress.
>> If you are doing dynamic loading, get the address exactly once, when you load the DLL, not
>> every time you call the function. Assume that the lookup of the name is very, very,
>> expensive.
>
>Actually, I'm not responsible for the CSerialCom. However I used it without 
>trying to understand ...
>Why is it bad to GetProcAddress every time? It takes much time to evaluate 
>the address? Therefore it's better to store the result, right?

*****
GetProcAddress by name lookup is very slow. Assume that it will be seriously slow. 
*****
>
>> 
>> Note that it is foolish to create a char array, particularly a char array of a fixed size.
>> GetProcAddress would work fine as
>> 
>> 	p = (LP2INT)GetProcAddress(hDLL, "READBYTE");
>> so why do you think you need to declare a separate variable for this purpose?
>> 
>> If you need to declare a separate variable (which is inappropriate here), you could
>> declare it as
>> 
>> const char szFuncName[] = "READBYTE";
>> 
>> but there is no reason to create the array at all; you could have done
>> 
>> const char * szFuncName = "READBYTE";
>> 
>> but neither of these make much sense in this particular context. Why introduce a
>> completely unnecessary separate variable to solve a nonexistent problem?
>> 
>Well, I'm not sure about that. The "READBYTE" has to be stored somewhere. If 
>it isn't explicitly linked to a variable, the compiler will assign it to a 
>place in memory. Moreover, change the array to a constant (const) doesn't 
>change anything, does it? It's then just a constant and can't be changed 
>contentwise. Besides the fact that memory is allocated everytime the function 
>is called, why don't you like the array? 
****
It is an issue of programming style. The general rule is to not introduce variables
without necessity. If the variable isn't necessary, don't introduce one. Yes, the string
has to be stored somewhere. So let the compiler store it (note that what you wrote
requires a copy each time the variable is initialized). Declaring it a const is good
practice, because you are not going to change it. 

I don't like the array because it is a waste of conceptual information. It adds nothing
functionally, but introduces several new concepts: a name, an initialization, a use of the
name, which merely increase the entropy of your program, making it harder to read an
understand. 

Do not introduce unnecessary variables into a program. This one is unnecessary.
*****
>
>char szFuncName[9] = "READBYTE"; 
>char *szFuncName = "READBYTE";
>
>Isn't it the same? 
****
Absolutely not. The first form creates an array of 9 characters, then copies the constant
string into the array. The second form creates a pointer, then copies a pointer to the
string into the variable. If you don't understand this, please go back and study
introductory C language texts.
****
>
>> If you want to do both input and output concurrently, you need to use asynchronous I/O;
>> presumably your DLL is doing this (although the use of a DLL to do a trivial task is
>> already suspect. Asynchrnonous serial I/O is relatively trivial to write in such a case).
>> 
>> I tend to use two threads: one for input, and one for output. Then if the ReadFile fails
>> on an ERROR_IO_PENDING I do a WaitForMultipleObjects on the event handle and a shutdown
>> event, where the shutdown event is the [0]th element of the array. This allows for
>> graceful shutdown. This allows you to set longer timeouts and get better response to
>> thread shutdown requests.
>> 
>It is is a small project for my studies and I don't wanted to spend too much 
>time on it. I'm not an expert either.  I/O seems to me pretty complex. It's 
>the first time that I'm using a thread and I just read a chapter in book 
>about it.  I don't have any practial experience on it.
>
>first it looked like:
>
>bool bThreadRunning = true;
>
>void CClass::Run()
>{
>     while(bThreadRunning)
>    {
>      ..........
>     }
>
>}
>
>void CClass::Stop()
>{
>   bThreadRunning = false;          // stop thread
>}
>
>
>The problem with that is the CPU load. I had to change it somehow ...
>
****
Then you got it wrong in the thread function. The thread function should block if there is
nothing to do. If it doesn't block, then it will consume 100% of the CPU. This indicates
an erroneous design. The fix is to fix the problem, not build a program that is even more
bizarre.
****
>
>> What I don't understand is why you are creating a thread each time you read a character.
>> This is horrendously inefficient. There is no need to do this.
>> 
>> There is no need to test pParam as you have done. It is simply an error to pass in a NULL,
>> so you should do
>> 
>> ASSERT(pParam != NULL)
>>  
>> if(pParam == NULL)
>>      return 0;
>> 
>> Forget return values other than 0; nobody cares about thread return values.
>> 
>ok, thanks
>
>> For more, see below...
>> 
>> On Thu, 17 Feb 2005 10:51:02 -0800, "Arno Kromke" <ArnoKromke@discussions.microsoft.com>
>> wrote:
>> 
>> >Hi,
>> >
>> >I'm working on a dialog based app that utilizes PC's serial port. Up to now, 
>> >the app is just capable  to send.  I'd like to extend it by receive 
>> >functionality. Actually, port I/O isn't the issue since I'm using a dll that 
>> >does it for me.  The issue I discovered is that I would lock my application 
>> >for user commands while waiting for some data to be received.  Data arrives 
>> >now and then - might be within a second or might take longer like 5 minites 
>> >...
>> >
>> > I applied a thread to workaround the locking of the application. But I 
>> >don't know if that is an appropriate technique solve this kind of 
>> >communication. I think it would be much better if my app gets notified  by 
>> >incomming data and only in this case the application reads from the port.  
>> >Does anyone have some suggestions? Whats appropriate for that?
>> >
>> >Here's what I did:
>> >
>> >- there's a port.dll that I'm interfacing thru a wrapper class CSerialCom
>> >- CSerialCom got member functions for open, close, send and read port 
>> >
>> >here's the member function that i use for reading from port in particular:
>> >
>> >int CSerialCom::ReadByte()
>> >{
>> >typedef int (CALLBACK* LP2INT)();
>> >char szFuncName[9] = "READBYTE";
>> >LP2INT p;
>> >p = (LP2INT)GetProcAddress(hDLL, szFuncName);
>> >    return p();
>> >
>> >}
>> >
>> >
>> >The following code is a snippet of my dialog based app where I create the 
>> >worker thread:
>> >...
>> >CWinThread* pThread = AfxBeginThread(threadHelperFunc, this);
>> >pThread->SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
>> >...
>> >
>> >// static function
>> >UINT CDspComDlg::threadHelperFunc(LPVOID pParam)
>> >{
>> >CDspComDlg* pApp = (CDspComDlg*) pParam;
>> >if (pApp)
>> >{
>> >  pApp->threadReceive();
>> >  return 1;
>> >}
>> >
>> >return 0;
>> >}
>> >
>> >
>> >
>> >void CDspComDlg::threadReceive(void)
>> >{
>> >	chBuffer = pCom->ReadByte();                     // pCom is object of 
>> >CSerialCom
>> >	if (bFirstByte)							// lower byte to be expected?
>> >	{
>> >
>> >		if (LowerByte != chBuffer)			// new data has been received
>> >		{
>> >			LowerByte = chBuffer;
>> >			bFirstByte = false;				// set flag, upper byte to be expected next
>> >		}
>> >	}
>> >	else
>> >	{
>> >		// we expect upper byte
>> >		if (UpperByte != chBuffer)
>> >		{
>> >			UpperByte = chBuffer;			// received data complete
>> >			bFirstByte = true;				// next will be lower byte
>> >			
>> >			// alignment
>> >			ReceivedValue = (short int)UpperByte;
>> >			ReceivedValue = ReceivedValue <<8;
>> >			ReceivedValue += (short int)LowerByte; 
>> >                 
>> >                       ...
>> >                       etc.
>> >                       ....
>> >		}
>> >	}
>> >	Sleep(1);
>> >}
>> >
>> >
>> This is about the most convoluted code I could imagine to accomplish a simple task. 
>> 
>> The code is incredibly simple:
>> 
>> chBuffer[0] = pCom->ReadByte();
>> chBuffer[1] = pCom->ReadByte();
>> ReceivedValue = *(short int *) chBuffer;
>> 
>> I have no idea why you have chosen to create the received value in such a complex fashion.
>> 	ReceivedValue = MAKEWORD(lowerByte, upperByte);
>
>I like your solution better ;-) very efficient in comparison to what I've 
>done. 
>
>> 
>> would have done the job without any complexity, but the whole business about trying to
>> figure out what byte you are reading and where to put it is needlessly complex.
>> 
>> Lose the Sleep(1). If your program doesn't work without it, you have such deep and
>> fundamental flaws that it isn't going to save you. 
>> 
>
>I think I can get rid of it. But what's wrong with Sleep? It's like a wait 
>for the working thread and returns computation time to the main thread.
>
>> Note that this code (both yours and mine) doesn't recover from serial port I/O errors.
>> Presumably they throw an exception; otherwise, you have to assume that the I/O completed.
>> In the case of trying to do asynchronous shutdown, this won't work very well. If you are
>> doing syncrhonous I/O, you are in seirously deep trouble anyway (you can't do concurrent
>> I/O, you can't shut down your program), so it is reasonably safe to assume that
>> asynchronous I/O is mandatory.
>> 
>> If the DLL isn't doing asynchronous I/O, scrap it. I posted the code for async I/O within
>> the last day on this newsgroup. 
>> 				joe
>
>Ok, I'll have a look at your i/o code. Thanks reviewing my code and for all 
>of your
>suggestions and qualified critics.
> 
>> >Thanks & Regards,
>> >
>> >Arno
>> 
>> Joseph M. Newcomer [MVP]
>> email: newcomer@flounder.com
>> Web: http://www.flounder.com
>> MVP Tips: http://www.flounder.com/mvp_tips.htm
>> 
>
>Arno

Joseph M. Newcomer [MVP]
email: newcomer@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
0
newcomer (15975)
2/20/2005 12:29:04 AM
Reply:

Similar Artilces:

Passing Data Between Threads
Hey There, I am writing some code that will create a worker thread from the main thread Data is created in a worker thread, and I need to pass that data back to the main thread, becuase I need to make sure that that data is unique every time a different worker thread is created. I am creating the the worker thread using AfxBeginThread. Any ideas? -Jay (patelj27b at gmail dot com) You can pass a buffer to the thread and have it fill the buffer for you. This method will require some synchronization. So read up on syncronization class in MSDN http://msdn2.microsoft.com/en-US/library/09afx...

debuggin multi threaded stuck application
Hello, We have a multithreaded MFC application. There is a new bug, that causes my application to be stuck. I don't know how to find the problem. I try to pause the application when it is stuck, I get to the same point everytime, but I don't know which is the thread that is stuck. I suspect one specific thread, the problem is that I don't know how to make sure. I cannot access none of the source code I see in the Call Stack. The first row inside the call stack (from bottom, hence the first caller function) is from GDIPlus, and the last one is in usr32 (MsgWaitForMutipleObjects) P...

Optimum numberof Job Processor Threads
We have a master project with 30 subprojects. I am running into issues during save wherefiles will hang up in the queue or in some cases Project Pro will crash and leave files checked out. Right now we have the maximum number of job processor threads set at the default 4. Would increasing the number help my situation? Is there a sweet spot? Is there a downside to increasing the number? Any help/thoughts would be appreciated. Thx R -- Raymond C. Day EVM Project Manager Serco North America Hi Raymond, Do you get any errors in the queue. There isn't an optimum num...

How to destroy a window created by other thread?
I write a simple program to monitor visible windows and close unexpected windows. The API function, DestroyWindow, does not work for the window is created by other thread. I use the following code: SendMessage(hwnd, WM_DESTROY, 0, 0); It does not work in all windows, say IE, OE. How to do it? Thank you. fadics wrote: > I write a simple program to monitor visible windows and close > unexpected windows. > > The API function, DestroyWindow, does not work for the window is > created by other thread. > > I use the following code: > SendMessage(hwnd, WM_DESTROY...

threads #4
If a thread has a finite lifetime, should we let it finish it self or should we call ExitThread when its work is done? Thanks. Jessica "Jessica Weiner" <jessica@gmail.com> wrote in message news:J111g.12236$4L1.5173@newssvr11.news.prodigy.com... | If a thread has a finite lifetime, should we let it finish it self or should | we call ExitThread when its work is done? | | Thanks. | Jessica | Just let it return, no worries (the simple answer) - Ed. On Tue, 18 Apr 2006 08:01:45 GMT, "Jessica Weiner" <jessica@gmail.com> wrote: >If a thread has a finit...

getting thread-ID from another thread
Hi, how is it possible to get the thread-ID for another thread which is already running? The postmessage is generated in thread A -> but the message should be transmitted to thread B; the problem is, that I don`t have a handle to thread B. PostThreadMessage(GetThreadId(), UWM_SEND_DATA, (WPARAM)msg, 0); Thread-A: proceed incoming data by ethernet Thread-B: write some code to the com-port1 Thread-C: write some code to the com-port2 and son on (8 com ports) - the code is nearly the one provided by Joseph M. Newcomer (http://www.flounder.com/serial.htm#SerialParameters) ...

When does the MFC thread CToolTipCtrl get created?
I'm trying to change the thread tooltip font using SetFont(). I'm able to access the control by accessing AfxGetModuleState()->m_thread.GetDataNA()->m_pToolTip. However, m_pToolTip is NULL if I call it in the initialization code (the app InitInstance() or the main frame OnCreate()). I assume it gets created only when the cursor is moved over a toolbar button or some such thing. So, the questions are: a) Does the tooltip get created multiple times or just once?, and b) Where does it get created? (so that I may change the font immediately thereafter) Thanks in advance, Sandeep ...

consolidating e-mail threads
When you are automatically tracking CRM mail (either via the Mail Router or via Outlook), and when you have a lengthy back-and-forth exchange with a customer, the CRM tracks each of these emails as a separate activity in CRM. Has anyone run across a solution (ISV or otherwise) that will consolidate those activities into one activity? It would seem possible, especially if using the tracking tokens. Thanks Dave Ireland Hi Dave, I think it's very hard to develop. Outlook has a conversation id (an email thread id) which could be used to identify emails being replies to other emai...

Sharing data between threads
Hi, I have a problem relating to sharing data between multiple threads. Basically, the problem I'm having is that I have a instance of a class I defined myself. I am spawning a child thread that runs a class function. ie. something like: CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)staticChildThread, (LPVOID)this, 0, &m_dwChildID); //staticChildThread is a member of the class This function alters class members as it is processing. The problem I'm having is that when I try to read these class members from the main thread, the values are unchanged. It is not until the very en...

SendInput to a window belonging to another application thread
I'm trying to develop a simple application that can send input to a window belonging to another application thread, such as the microsoft on screen keyboard. The matter is that I don't understand how to know what was the last active window to which send the input from my dialog application. Looking on internet I've found a simple application called "Typematic" but it hide the application dialog before use the SendInput() api, it works well but I wish to obtain the same effect without hide the application dialog as the on screen keyboard does. How I could do it? Ho...

Hyper-Threading Technology for XP with Excel 2000
Attention to: Microsoft Expert My computer setting is Dual-XEON 2.66, 1GB RAM with Windows XP Professional. Hyper-Threading Technology is enabled, therefore, I am able to see four logical Processors. However, when I open single Excel 2000 spreadsheet for calculation, it consumes 25% of CPU and 130MB RAM on computing resources. If I disable Hyper- Threading Technology, then it displays only 2 CPU processors only, and I try to run the same single Excel 2000 spreadsheet for calculation, it consumes 50% of CPU, of course, the speed of calculation is faster. Could you tell me why Hype...

Thread #4
Hi to all.. I am using MFC regular dll, this dll execcute the call back functions. In client functions resume the thread based on one simple conditions BOOL bThreadFlag; with in dll client function BOOL fn_clientCallBack(void *sFile) { if(bThredFlag) /*Resume the Client Thread*/ m_ThreadEncoder->ResumeThread(); } the above functions set into call back that is excuted in dll thread. Note: fn_clientCallBack(void *sFile) act as a call back My problem is the dll the thread excuted first and then it call the client functions(fn_clientCallBack(void *sFile) act as a call back) that ...

how i come to know that thread has been finished
Hi guys, can you please tell me that how i come to know that running Thread has been finished. On 6 Jun 2006 04:08:53 -0700, raghunandan_1081@yahoo.com wrote: >Hi guys, can you please tell me that how i come to know that running >Thread has been finished. The only foolproof way is to call WaitForSingleObject or other wait function; if you find the thread handle signaled, the thread has finished. To use those functions safely with CWinThread, see: http://members.cox.net/doug_web/threads.htm -- Doug Harrison Visual C++ MVP DWORD result = WaitForSingleObject(hThreadHandle, 0); if ...

A _very_ basic question about WM_TIMER and threading
Hi, If I create a timer by calling CWnd::SetTimer() (e.g. in my CView::OnInitialUpdate()) why do I need to deal with re-entrancy issues in the corresponding OnTimer() handler? I thought that all calls to OnTimer() handlers execute on the same thread (main GUI thread?). How is it possible then for the handler to be called while the thread is already executing the handler? I've run into this problem recently while debugging my app. I'd welcome any pointers and/or explanations. Thanks. andrew wrote: > Hi, > > If I create a timer by calling CWnd::SetTimer() (e.g. in...

2.0 Threads, Join() and Invoke
Hi, I just want to run several threads at the same time. The code below just hang because - I guess - it can't access the TextBox.Text method. What is wrong with tis code ?! Thanks. Melina. public class Report { public TextBox _log; private List<RptTemplate> _listeTemplate; private List<CIF> _listeCIF; public Report(TextBox logTextBox, List<RptTemplate> listeTemplate, List<CIF> listeCIF) { _log = logTextBox; _listeTemplate = listeTemplate; _listeCIF = lis...

Disable multi-threading in Excel 2007
We are running Excel 2007 in a Terminal Server environment and do not want one instance of Excel 2007 to consume more than one core at a time. I know how to disable it via the GUI, but this must be done manually per user. How does one force this change via Group Policy or a registry entry? Any help would be appreciated. Thanks. Can you use a workbook.open event in a startup workbook to set application.multithreadedcalculation.enabled=False? Charles __________________________________________________ The Excel Calculation Site http://www.decisionmodels.com "Bradley Smith" &l...

How Dialog Can Check Thread Status?
I am beginning a thread when a button is pressed in a modal dialog. I want to be able send status back to the dialog so I can display it in a edit box. The thread is running a test on a SCSI device so I want to display status as test progresses. Any help on how I might go about accomplishing this would greatly be appreciated. I am noivce windows programmer so please bare this in mind. Steve Heck wrote: > > I am beginning a thread when a button is pressed in a > modal dialog. I want to be able send status back to the > dialog so I can display it in a edit box. The thread is...

Threading in Order?
I have a background task (thread) of logging messages, so that I do not take execution time away from the main web application. Unfortunately, the messages are not stored in order of occurrence. How can I set up a queue, pool, single pipe (whatever is necessary), so that threads are executed in the order, or more specifically, the messages are stored in the order, in which they are started? Thanks. Rico wrote: > I have a background task (thread) of logging messages, so that I do > not take execution time away from the main web application. > > Unfortunately, the ...

quoting all the threads in the postings
This is a common subject for all the newsgroups I raised this poiint earlier. somebody said tht the message would be too long if there are too many threads for the same subject. But my problem is suppose some subject in the newsgroup headers interests me and I click I get a thread "brilliant, it works" and nothing else. I would like to know this brilliant suggestion so that I can be more educated. Of course I can copy and paste in the google groups search (availabele in Opera browser) and get all the threads. I would like to have comments from my peers. I very much support th...

How to use IO Completion Port to exchange data between two threads
Hello I have heard that I can exchange data between 2 threads using IO Completion Port but MSDN had no example and I could not find a specific explanation about this. Should I create a IO Completion Port in each thread and then Read and Write to a file created by CreateFile using ReadFile, WriteFile? thanks See my MVP Tips site. The specific article is http://www.flounder.com/iocompletion.htm Simple: PostQueuedCompletionStatus to send a notification and GetQueuedCompletionStatus to retrieve it. That's all there is to it. In the case of the main GUI thread, I show how to avoid mes...

Terminate worker thread when Dialog closes
I have a CDialog that spawns a worker thread. How do I terminate the thread when the dialog box closes (and the CDialog class is destroyed)? Si wrote: > I have a CDialog that spawns a worker thread. How do I terminate the thread > when the dialog box closes (and the CDialog class is destroyed)? Signal the worker thread to close itself, and then wait until it has closed. If the thread is executing a loop you can signal it by setting a bool that it tests. If the thread is suspended by a WaitFor... call then use an event (CreateEvent, SetEvent) in the list of things it is waiti...

std::vector and multi-threading
Are std::vector and other aspects of standard template library safe to use in a multi-threaded environment as long as only a single thread needs access to this memory? What kinds of things would I need to do if multiple threads need access to memory? Peter Olcott wrote: > Are std::vector and other aspects of standard template library > safe to use in a multi-threaded environment as long as only a > single thread needs access to this memory? > > What kinds of things would I need to do if multiple threads need > access to memory? > > Yes, there are no issu...

maintenance thread error
ms exchange 5.5 information store stops with a maintenance thread error. we can restart exchange and it works any ideas Cut / Paste the event from the application log. -- Hope that helps, Dan Townsend This posting is provided "AS IS" with no warranties, and confers no rights. Please do not send email to this address, post a reply to this newsgroup. Use of included script samples are subject to the terms specified at http://www.microsoft.com/info/cpyright.htm "rene'" <anonymous@discussions.microsoft.com> wrote in message news:07e601c3faed$f1ccf480$a301280a@p...

Message threads #2
Earlier in OE, all sent and received mail moved into a Folder, would appear in chronological order. Now after migrating to Outlook, the received mail appears seperatley and the sent mail appears seperately, both in chronological order. How do I get them to appear together in sequence i.e. in chronological order? What version of Outlook? Is there any grouping on the folder view? Are you sending replies and forwards to the folder where the original message resides? -- Jocelyn Fiorello *** Messages sent to my e-mail address will NOT be answered -- please reply only to the newsgroup to...

worker thread and PostThreadMessage with WM_QUIT
That known way to stop MFC worker thread with thread->PostThreadMessage(WM_QUIT) But how it's done ? The thread have no message loop and all the body of thread function is unsigned int func( LPVOID par ) { while(TRUE) ; } And nevertheless WM_QUIT stop the thread . TIA Arkady Arkady Frenkel wrote: >That known way to stop MFC worker thread with > >thread->PostThreadMessage(WM_QUIT) > >But how it's done ? The thread have no message loop and all the body of >thread function is >unsigned int func( LPVOID par ) >{ > while(TRUE) ; >} >And ne...