Thread Question
-
Hi all! I'm on a ciphering Win32 project and i have the following problem: I have created the thread and I don't use SendMessage calls inside the thread procedure. I use PostMessage with user defined messages to display progress information on the main window. But when the thread starts the whole program dead locks. Is that means that it needs a Sleep function or something else that you could suggest me? Thanks!
-
Hi all! I'm on a ciphering Win32 project and i have the following problem: I have created the thread and I don't use SendMessage calls inside the thread procedure. I use PostMessage with user defined messages to display progress information on the main window. But when the thread starts the whole program dead locks. Is that means that it needs a Sleep function or something else that you could suggest me? Thanks!
Show code. Could be anything, you could -maybe- be flooding your GUI thread with messages, or maybe your thread is a run-away thead (it eats up all the CPU time so your GUI has no chanche to do anything), or it could be a deadlock caused by a cross-lock problem, or or or...
> The problem with computers is that they do what you tell them to do and not what you want them to do. < > Life: great graphics, but the gameplay sux. <
-
Hi all! I'm on a ciphering Win32 project and i have the following problem: I have created the thread and I don't use SendMessage calls inside the thread procedure. I use PostMessage with user defined messages to display progress information on the main window. But when the thread starts the whole program dead locks. Is that means that it needs a Sleep function or something else that you could suggest me? Thanks!
-
Show code. Could be anything, you could -maybe- be flooding your GUI thread with messages, or maybe your thread is a run-away thead (it eats up all the CPU time so your GUI has no chanche to do anything), or it could be a deadlock caused by a cross-lock problem, or or or...
> The problem with computers is that they do what you tell them to do and not what you want them to do. < > Life: great graphics, but the gameplay sux. <
The code is:
// When user presses the start button
void DataCryptMain ::ProcessCrypt()
{
...
cryptthread.Start(_staticThreadProc, this)
...
}// Crypt procedures
DWORD WINAPI _staticThreadProc(LPVOID lpData)
{
DataCryptMain *dcr = reinterpret_cast(lpData);
return dcr->CryptThreadProc(NULL);
}DWORD WINAPI DataCryptMain::CryptThreadProc(LPVOID lpData)
{
int iErrorOrInfo = INFO_PROCESS_DONE;// Ciphering stuff
iErrorOrInfo = CryptoRijnDaelProcess();Notify_Progress_GUI(NOTIFY_PROGRESS_END, NULL, iErrorOrInfo);
return 0;
}// Notify GUI
void DataCryptMain::Notify_Progress_GUI(int iNotificationType, WPARAM wParam, LPARAM lParam)
{if (iNotificationType == NOTIFY_PROGRESS_RUNNING)
{
PostMessage(hWnd, WM_PROGRESS_RUNNING, wParam, lParam);
}
else
{
PostMessage(hWnd, WM_PROGRESS_END, wParam, lParam);
}}
// Call back procedure from inside Encrypt()
bool _ProgressBarProc(PRBDATA *prbdata)
{
DataCryptMain *dcr = reinterpret_cast(prbdata->lpOtherData);
return dcr->ProgressBarProc(prbdata);
}bool DataCryptMain::ProgressBarProc(PRBDATA *prbdata)
{
if (cryptthread.WaitToExit()) return TRUE;PRBDATA *_prbdata = new PRBDATA;
memcpy(_prbdata, prbdata, sizeof(PRBDATA));
Notify_Progress_GUI(NOTIFY_PROGRESS_RUNNING, NULL, (LPARAM)_prbdata);
return FALSE;
}// Rijndael processing
int DataCryptMain::CryptoRijnDaelProcess()
{
int iErrorOrInfo = OK;RijnDaelCrypto *rdc = new RijnDaelCrypto;
...
...// Set progress bar function
SetProgressFunc(_ProgressBarProc, (LPVOID)this);------------------- Here this function loops through the file encryption
if (rdc->Encrypt(wcgFileNameIn, wcgFileNameOut, cryptParams.iCipherMode) < 0)
iErrorOrInfo = ERR_PROCESS_STOPPED_BY_USER;_DELETE(rdc);
return iErrorOrInfo;
}//WM_PROGRESS_RUNNING
bool DataCryptMain::OnProgressRunning(WPARAM wParam, LPARAM lParam)
{
float fPercent[3];
char sTemp[64];PRBDATA \*prbdata = reinterpret\_cast(lParam); // Percent % read file fPercent\[0\] = ((float)prbdata->iReadBytesIncByFuncRead / (float)prbdata->dwSize) \* 100.0f; // Percent % block/s processed fPercent\[1\] = ((float)prbdata->iBlocksIncrement / (float)prbdata->iBlocksNum) \* 100.0f; // Average percent fPercent\[2\] = (fPercent\[0\] + fPercent\[1\]) / 2; SendDlgItemMessage(hWnd, IDC\_PROGRESSSTATUS, PBM\_SETPOS, (WPARAM)fPercent\[2\], 0); // Display progress bar's percent value sprintf\_s(sTemp, "%0.1f %%", fPercent\[
-
The code is:
// When user presses the start button
void DataCryptMain ::ProcessCrypt()
{
...
cryptthread.Start(_staticThreadProc, this)
...
}// Crypt procedures
DWORD WINAPI _staticThreadProc(LPVOID lpData)
{
DataCryptMain *dcr = reinterpret_cast(lpData);
return dcr->CryptThreadProc(NULL);
}DWORD WINAPI DataCryptMain::CryptThreadProc(LPVOID lpData)
{
int iErrorOrInfo = INFO_PROCESS_DONE;// Ciphering stuff
iErrorOrInfo = CryptoRijnDaelProcess();Notify_Progress_GUI(NOTIFY_PROGRESS_END, NULL, iErrorOrInfo);
return 0;
}// Notify GUI
void DataCryptMain::Notify_Progress_GUI(int iNotificationType, WPARAM wParam, LPARAM lParam)
{if (iNotificationType == NOTIFY_PROGRESS_RUNNING)
{
PostMessage(hWnd, WM_PROGRESS_RUNNING, wParam, lParam);
}
else
{
PostMessage(hWnd, WM_PROGRESS_END, wParam, lParam);
}}
// Call back procedure from inside Encrypt()
bool _ProgressBarProc(PRBDATA *prbdata)
{
DataCryptMain *dcr = reinterpret_cast(prbdata->lpOtherData);
return dcr->ProgressBarProc(prbdata);
}bool DataCryptMain::ProgressBarProc(PRBDATA *prbdata)
{
if (cryptthread.WaitToExit()) return TRUE;PRBDATA *_prbdata = new PRBDATA;
memcpy(_prbdata, prbdata, sizeof(PRBDATA));
Notify_Progress_GUI(NOTIFY_PROGRESS_RUNNING, NULL, (LPARAM)_prbdata);
return FALSE;
}// Rijndael processing
int DataCryptMain::CryptoRijnDaelProcess()
{
int iErrorOrInfo = OK;RijnDaelCrypto *rdc = new RijnDaelCrypto;
...
...// Set progress bar function
SetProgressFunc(_ProgressBarProc, (LPVOID)this);------------------- Here this function loops through the file encryption
if (rdc->Encrypt(wcgFileNameIn, wcgFileNameOut, cryptParams.iCipherMode) < 0)
iErrorOrInfo = ERR_PROCESS_STOPPED_BY_USER;_DELETE(rdc);
return iErrorOrInfo;
}//WM_PROGRESS_RUNNING
bool DataCryptMain::OnProgressRunning(WPARAM wParam, LPARAM lParam)
{
float fPercent[3];
char sTemp[64];PRBDATA \*prbdata = reinterpret\_cast(lParam); // Percent % read file fPercent\[0\] = ((float)prbdata->iReadBytesIncByFuncRead / (float)prbdata->dwSize) \* 100.0f; // Percent % block/s processed fPercent\[1\] = ((float)prbdata->iBlocksIncrement / (float)prbdata->iBlocksNum) \* 100.0f; // Average percent fPercent\[2\] = (fPercent\[0\] + fPercent\[1\]) / 2; SendDlgItemMessage(hWnd, IDC\_PROGRESSSTATUS, PBM\_SETPOS, (WPARAM)fPercent\[2\], 0); // Display progress bar's percent value sprintf\_s(sTemp, "%0.1f %%", fPercent\[
At the first look i don't see any obvious errors (althorough they might be there and i am a blind mouse). Try pausing your (DEBUG build) programs's execution in VS (with the pause button on the toolbar for example) and check what your threads are doing, you might find out what your GUI thread seems to be waiting for. You could also try placing a sleep here and there to see if the situation gets any better or not, if it does then most likely it's the "run away thread" thing, or try removing the PostMessage from the thread temporarily, or make it Post a message every 100th time it is called and run your program to see if your GUI is reponsive or not, if it is, than it is likely you are flooding it with the "status-report" messages.
> The problem with computers is that they do what you tell them to do and not what you want them to do. < > Life: great graphics, but the gameplay sux. <
-
At the first look i don't see any obvious errors (althorough they might be there and i am a blind mouse). Try pausing your (DEBUG build) programs's execution in VS (with the pause button on the toolbar for example) and check what your threads are doing, you might find out what your GUI thread seems to be waiting for. You could also try placing a sleep here and there to see if the situation gets any better or not, if it does then most likely it's the "run away thread" thing, or try removing the PostMessage from the thread temporarily, or make it Post a message every 100th time it is called and run your program to see if your GUI is reponsive or not, if it is, than it is likely you are flooding it with the "status-report" messages.
> The problem with computers is that they do what you tell them to do and not what you want them to do. < > Life: great graphics, but the gameplay sux. <
If it works as i've shown it uses about 86% of CPU, the changes are displayed but I can't, for example, move the window or push a button. If i place a sleep function then it works OK About the first you'said, i didn't understand "you might find out what your GUI thread seems to be waiting for"
-
The code is:
// When user presses the start button
void DataCryptMain ::ProcessCrypt()
{
...
cryptthread.Start(_staticThreadProc, this)
...
}// Crypt procedures
DWORD WINAPI _staticThreadProc(LPVOID lpData)
{
DataCryptMain *dcr = reinterpret_cast(lpData);
return dcr->CryptThreadProc(NULL);
}DWORD WINAPI DataCryptMain::CryptThreadProc(LPVOID lpData)
{
int iErrorOrInfo = INFO_PROCESS_DONE;// Ciphering stuff
iErrorOrInfo = CryptoRijnDaelProcess();Notify_Progress_GUI(NOTIFY_PROGRESS_END, NULL, iErrorOrInfo);
return 0;
}// Notify GUI
void DataCryptMain::Notify_Progress_GUI(int iNotificationType, WPARAM wParam, LPARAM lParam)
{if (iNotificationType == NOTIFY_PROGRESS_RUNNING)
{
PostMessage(hWnd, WM_PROGRESS_RUNNING, wParam, lParam);
}
else
{
PostMessage(hWnd, WM_PROGRESS_END, wParam, lParam);
}}
// Call back procedure from inside Encrypt()
bool _ProgressBarProc(PRBDATA *prbdata)
{
DataCryptMain *dcr = reinterpret_cast(prbdata->lpOtherData);
return dcr->ProgressBarProc(prbdata);
}bool DataCryptMain::ProgressBarProc(PRBDATA *prbdata)
{
if (cryptthread.WaitToExit()) return TRUE;PRBDATA *_prbdata = new PRBDATA;
memcpy(_prbdata, prbdata, sizeof(PRBDATA));
Notify_Progress_GUI(NOTIFY_PROGRESS_RUNNING, NULL, (LPARAM)_prbdata);
return FALSE;
}// Rijndael processing
int DataCryptMain::CryptoRijnDaelProcess()
{
int iErrorOrInfo = OK;RijnDaelCrypto *rdc = new RijnDaelCrypto;
...
...// Set progress bar function
SetProgressFunc(_ProgressBarProc, (LPVOID)this);------------------- Here this function loops through the file encryption
if (rdc->Encrypt(wcgFileNameIn, wcgFileNameOut, cryptParams.iCipherMode) < 0)
iErrorOrInfo = ERR_PROCESS_STOPPED_BY_USER;_DELETE(rdc);
return iErrorOrInfo;
}//WM_PROGRESS_RUNNING
bool DataCryptMain::OnProgressRunning(WPARAM wParam, LPARAM lParam)
{
float fPercent[3];
char sTemp[64];PRBDATA \*prbdata = reinterpret\_cast(lParam); // Percent % read file fPercent\[0\] = ((float)prbdata->iReadBytesIncByFuncRead / (float)prbdata->dwSize) \* 100.0f; // Percent % block/s processed fPercent\[1\] = ((float)prbdata->iBlocksIncrement / (float)prbdata->iBlocksNum) \* 100.0f; // Average percent fPercent\[2\] = (fPercent\[0\] + fPercent\[1\]) / 2; SendDlgItemMessage(hWnd, IDC\_PROGRESSSTATUS, PBM\_SETPOS, (WPARAM)fPercent\[2\], 0); // Display progress bar's percent value sprintf\_s(sTemp, "%0.1f %%", fPercent\[
The code you posted is horribly formatted and missing < and > symbols and what's between them.
Steve
-
If it works as i've shown it uses about 86% of CPU, the changes are displayed but I can't, for example, move the window or push a button. If i place a sleep function then it works OK About the first you'said, i didn't understand "you might find out what your GUI thread seems to be waiting for"
Dennis L wrote:
About the first you'said, i didn't understand "you might find out what your GUI thread seems to be waiting for"
I mean, when you break the execution of your program you can check out where that execution was in your code (assuming you have debug information) so you can see where your GUI thread gets stuck, the debugger shows you, it will point at the place where the program was halted. But if everything works with a sleep then for now you can forget about this part. Where did you place the sleep? Does this sleep slow down the thread that is posting the messages towards your GUI thread? If yes, then i'd say you are flooding your GUI with messages. Try to decrease the number of messages sent to your GUI, for example, send only every 10th status report, or check when you sent the last report and if a given amount of time (like,for exaple 100 ms) didn't ellapse yet then skip sending the message, OR perform the percentage calculation in your thread and only send a message towards the GUI if the new percentage is different from the previous one, this should reduce the messages heading towards the GUI to not more than around a 100 messages per run, which shouldn't be too much, unless you are some very low end hardware.
> The problem with computers is that they do what you tell them to do and not what you want them to do. < > Life: great graphics, but the gameplay sux. <
-
Dennis L wrote:
About the first you'said, i didn't understand "you might find out what your GUI thread seems to be waiting for"
I mean, when you break the execution of your program you can check out where that execution was in your code (assuming you have debug information) so you can see where your GUI thread gets stuck, the debugger shows you, it will point at the place where the program was halted. But if everything works with a sleep then for now you can forget about this part. Where did you place the sleep? Does this sleep slow down the thread that is posting the messages towards your GUI thread? If yes, then i'd say you are flooding your GUI with messages. Try to decrease the number of messages sent to your GUI, for example, send only every 10th status report, or check when you sent the last report and if a given amount of time (like,for exaple 100 ms) didn't ellapse yet then skip sending the message, OR perform the percentage calculation in your thread and only send a message towards the GUI if the new percentage is different from the previous one, this should reduce the messages heading towards the GUI to not more than around a 100 messages per run, which shouldn't be too much, unless you are some very low end hardware.
> The problem with computers is that they do what you tell them to do and not what you want them to do. < > Life: great graphics, but the gameplay sux. <
I have placed the Sleep in the progress callback function as:
bool DataCryptMain::ProgressBarProc(PRBDATA *prbdata)
{
...
Notify_Progress_GUI(NOTIFY_PROGRESS_RUNNING, NULL, (LPARAM)_prbdata);
Sleep(1);
}You said: "Try to decrease the number of messages sent to your GUI, for example, send only every 10th status report, or check when you sent the last report and if a given amount of time (like,for exaple 100 ms) didn't ellapse yet then skip sending the message, OR perform the percentage calculation in your thread and only send a message towards the GUI if the new percentage is different from the previous one, this should reduce the messages heading towards the GUI to not more than around a 100 messages per run, which shouldn't be too much, unless you are some very low end hardware" All these i'll try them by using PostMessage or SendMessage?