Hi,
I have written a simple program that does the following:
The main program will spown MAX_THREADS number of threads, each
of which will simply add to a global shared counter for MAX_COUNT
times and notify the main thread it has finished by clearing a
mutex before exiting. The main thread will simply check verify the
final result in the global shared counter, wait for each worker
thread has notify finishing, and exit.
The complete C program is at the end of this message. Anyway,
the problem is not in the logic of this program. It is really an
anomaly I encountered while testing it with different values of
MAX_THREADS.
I found that for some reason, if the MAX_THREADS value is 1 or 2 the
hRunMutex[0] will be corrupted during execution for no apparent
reason. The program will go into an infinite loop in CheckCounter()
function. I can detect this by checking if the return value of
WaitForSingleObject() function equals WAIT_FAILED, etc, but that's
another topic. So I was playing with the program and tried to
print out the value of hRunMutex[0] at various points and I found
that if I add on extra global variable definition, the whole problem
goes away! That is if I add "char func[10];".
For MAX_THREADS value 3 and above, the program works well with
or without that line. But for value 1 and 2, it has to have that line.
Otherwise it gets a currupt handle during execution and could not
finish.
I am really curious about the cause of this problem. I'd appreciate
if anyone can shed some light on it for me, because besides blaming
Microsoft, I am completely clueless. :)
And the reason I am blaming Microsoft is I am using Visual Studio
..NET to compile the program. Just create a project with Managed C++
Empty Project, and add this file to project to compile and run it.
Thanks!
Regards,
James
/* counters.c file.*/
/* This program will create MAX_THREADS number of threads. Each of
them
* will increment a shared counter for MAX_COUNT times, sleeping for a
* random number of milliseconds in between each increment. The main
* thread will wait until the shared counter reaches
MAX_THREADS*MAX_COUNT.
* It will then wait for enter key from input before exiting to allow
* examining the output.
*/
#include <windows.h>
#include <stdio.h>
#include <process.h>
#define MAX_THREADS 2
#define MAX_COUNT 3
/* getrandom returns a random number between min and max. */
#define getrandom( min, max ) ((rand() % (int)(((max) + 1) - (min))) +
(min))
int main( void ); /* Thread 1: main */
void CountProc( int * MyID ); /* Threads 2 to MAX_THREADS:
Increment the shared counter */
void CheckCounter( void ); /* Function CheckCounter called
by main() */
void WriteMsg( int iThreadNum, int iMyCount, int iTotalCount ); /*
Display information */
HANDLE hRunMutex[MAX_THREADS]; /* Notification mutex */
int iThreadNum; /* Number of threads started */
HANDLE hCounterMutex; /* Shared counter mutex */
int iSharedCounter; /* Shared counter used by all threads
*/
int ThreadID[MAX_THREADS]; /* Thread ID for diaplay */
int done[MAX_THREADS] = {0}; /* Array for thread status */
char func[10]; // Necessary to make it work for MAX_THREADS = 1
and 2 cases. Microsoft bug?!
int main() /* Thread One */
{
/* Create the mutexes and reset thread count. */
int i;
iSharedCounter = 0;
for(i=0;i< MAX_THREADS;i++)
{
hRunMutex[i] = CreateMutex( NULL, TRUE, NULL ); /* Set */
}
hCounterMutex = CreateMutex( NULL, FALSE, NULL ); /* Cleared */
iThreadNum = 0;
WriteMsg( 0, 0, iSharedCounter );
/* Create the counting threads. */
while( iThreadNum < MAX_THREADS )
{
iThreadNum++;
ThreadID[iThreadNum] = iThreadNum;
_beginthread( CountProc, 0, &ThreadID[iThreadNum] );
}
/* Wait until the shared counter reaches the limit. */
CheckCounter();
WriteMsg( 0, 0, iSharedCounter );
/* All threads done. Clean up handles. */
for(i=0;i<MAX_THREADS;i++)
{
/* if(done[i] != 1) */
CloseHandle( hRunMutex[i] );
}
CloseHandle( hCounterMutex);
/* Pause for 10 seconds before exiting */
printf("Press enter to exit...");
getchar();
}
void CheckCounter( void ) /* Check shared counter */
{
int i;
/* Check the share counter limit, sleep in between each check */
while ( iSharedCounter < MAX_COUNT * MAX_THREADS)
{
Sleep(getrandom(0,100));
}
/* Wait for the woker threads to exit first */
while ( iThreadNum > 0 )
{
for(i = 0;i<MAX_THREADS;i++)
{
if(done[i] == 0 )
{
int ret = WaitForSingleObject( hRunMutex[i], 100 );
if(ret == WAIT_OBJECT_0 /*|| ret == WAIT_FAILED*/)
{
iThreadNum--;
done[i]=ret+2;
}
}
}
Sleep(getrandom(0,100));
}
}
void CountProc( int *MyID )
{
int i=0;
do
{
/* Wait for counter to be available, then lock it. */
WaitForSingleObject( hCounterMutex, INFINITE );
iSharedCounter++;
WriteMsg(*MyID, i, iSharedCounter);
ReleaseMutex( hCounterMutex );
i++;
Sleep(getrandom(0, 5));
}
while(i < MAX_COUNT);
ReleaseMutex( hRunMutex[(*MyID)-1] );
}
void WriteMsg( int iThreadNum, int iMyCount, int iTotalCount )
{
printf("Thread ID: %d, Local Count: %d, Shared Count: %d \n",
iThreadNum, iMyCount, iTotalCount );
} 2 1722
"James Niceguy" <or*****@yahoo.com> wrote in
news:11**********************@f14g2000cwb.googlegr oups.com: Hi,
I have written a simple program that does the following:
The main program will spown MAX_THREADS number of threads, each
Off-topic.... Standard C++ says nothing about Threads.
of which will simply add to a global shared counter for MAX_COUNT times and notify the main thread it has finished by clearing a mutex before exiting. The main thread will simply check verify the
Off-topic.... Standard C++ says nothing about Mutexes.
final result in the global shared counter, wait for each worker thread has notify finishing, and exit.
The complete C program is at the end of this message. Anyway, the problem is not in the logic of this program. It is really an anomaly I encountered while testing it with different values of MAX_THREADS. I found that for some reason, if the MAX_THREADS value is 1 or 2 the hRunMutex[0] will be corrupted during execution for no apparent reason. The program will go into an infinite loop in CheckCounter() function. I can detect this by checking if the return value of WaitForSingleObject() function equals WAIT_FAILED, etc, but that's another topic. So I was playing with the program and tried to print out the value of hRunMutex[0] at various points and I found that if I add on extra global variable definition, the whole problem goes away! That is if I add "char func[10];".
For MAX_THREADS value 3 and above, the program works well with or without that line. But for value 1 and 2, it has to have that line. Otherwise it gets a currupt handle during execution and could not finish.
I am really curious about the cause of this problem. I'd appreciate if anyone can shed some light on it for me, because besides blaming Microsoft, I am completely clueless. :)
And the reason I am blaming Microsoft is I am using Visual Studio .NET to compile the program. Just create a project with Managed C++ Empty Project, and add this file to project to compile and run it.
Thanks!
Regards, James
/* counters.c file.*/
/* This program will create MAX_THREADS number of threads. Each of them * will increment a shared counter for MAX_COUNT times, sleeping for a * random number of milliseconds in between each increment. The main * thread will wait until the shared counter reaches MAX_THREADS*MAX_COUNT. * It will then wait for enter key from input before exiting to allow * examining the output. */
#include <windows.h> #include <stdio.h> #include <process.h>
#define MAX_THREADS 2 #define MAX_COUNT 3
/* getrandom returns a random number between min and max. */ #define getrandom( min, max ) ((rand() % (int)(((max) + 1) - (min))) + (min))
int main( void ); /* Thread 1: main */ void CountProc( int * MyID ); /* Threads 2 to MAX_THREADS: Increment the shared counter */ void CheckCounter( void ); /* Function CheckCounter called by main() */ void WriteMsg( int iThreadNum, int iMyCount, int iTotalCount ); /* Display information */
HANDLE hRunMutex[MAX_THREADS]; /* Notification mutex */ int iThreadNum; /* Number of threads started */ HANDLE hCounterMutex; /* Shared counter mutex */ int iSharedCounter; /* Shared counter used by all threads */ int ThreadID[MAX_THREADS]; /* Thread ID for diaplay */ int done[MAX_THREADS] = {0}; /* Array for thread status */
char func[10]; // Necessary to make it work for MAX_THREADS = 1 and 2 cases. Microsoft bug?!
int main() /* Thread One */ { /* Create the mutexes and reset thread count. */ int i; iSharedCounter = 0; for(i=0;i< MAX_THREADS;i++) { hRunMutex[i] = CreateMutex( NULL, TRUE, NULL ); /* Set */ } hCounterMutex = CreateMutex( NULL, FALSE, NULL ); /* Cleared */ iThreadNum = 0;
WriteMsg( 0, 0, iSharedCounter );
/* Create the counting threads. */ while( iThreadNum < MAX_THREADS ) { iThreadNum++; ThreadID[iThreadNum] = iThreadNum;
Undefined behaviour. The second time through this loop, you increment
iThreadNum (making it 2) and then attempted to write into an array beyond
its bounds (ThreadID, only has elements 0 and 1).
_beginthread( CountProc, 0, &ThreadID[iThreadNum] ); }
/* Wait until the shared counter reaches the limit. */ CheckCounter(); WriteMsg( 0, 0, iSharedCounter );
/* All threads done. Clean up handles. */ for(i=0;i<MAX_THREADS;i++) { /* if(done[i] != 1) */ CloseHandle( hRunMutex[i] ); } CloseHandle( hCounterMutex);
/* Pause for 10 seconds before exiting */ printf("Press enter to exit..."); getchar(); }
void CheckCounter( void ) /* Check shared counter */ { int i;
/* Check the share counter limit, sleep in between each check */ while ( iSharedCounter < MAX_COUNT * MAX_THREADS) { Sleep(getrandom(0,100)); }
/* Wait for the woker threads to exit first */ while ( iThreadNum > 0 ) { for(i = 0;i<MAX_THREADS;i++) { if(done[i] == 0 ) { int ret = WaitForSingleObject( hRunMutex[i], 100 ); if(ret == WAIT_OBJECT_0 /*|| ret == WAIT_FAILED*/) { iThreadNum--; done[i]=ret+2; } } } Sleep(getrandom(0,100)); } }
void CountProc( int *MyID ) { int i=0; do { /* Wait for counter to be available, then lock it. */ WaitForSingleObject( hCounterMutex, INFINITE ); iSharedCounter++; WriteMsg(*MyID, i, iSharedCounter); ReleaseMutex( hCounterMutex );
i++; Sleep(getrandom(0, 5)); } while(i < MAX_COUNT);
ReleaseMutex( hRunMutex[(*MyID)-1] ); }
void WriteMsg( int iThreadNum, int iMyCount, int iTotalCount ) { printf("Thread ID: %d, Local Count: %d, Shared Count: %d \n", iThreadNum, iMyCount, iTotalCount ); }
Hi Andre,
Thank you for the answer! You are right on!! I changed the line to:
ThreadID[iThreadNum-1] = iThreadNum;
and the program works like a charm. Sorry if the policy is not to
discuss off-topic issues here. I will read the rules next time. Guess
I shouldn't be blaming MS so readily!
Regards,
James
Andre Kostur wrote: "James Niceguy" <or*****@yahoo.com> wrote in news:11**********************@f14g2000cwb.googlegr oups.com:
Hi,
I have written a simple program that does the following:
The main program will spown MAX_THREADS number of threads, each Off-topic.... Standard C++ says nothing about Threads.
of which will simply add to a global shared counter for MAX_COUNT times and notify the main thread it has finished by clearing a mutex before exiting. The main thread will simply check verify the
Off-topic.... Standard C++ says nothing about Mutexes.
final result in the global shared counter, wait for each worker thread has notify finishing, and exit.
The complete C program is at the end of this message. Anyway, the problem is not in the logic of this program. It is really an anomaly I encountered while testing it with different values of MAX_THREADS. I found that for some reason, if the MAX_THREADS value is 1 or 2
the hRunMutex[0] will be corrupted during execution for no apparent reason. The program will go into an infinite loop in CheckCounter() function. I can detect this by checking if the return value of WaitForSingleObject() function equals WAIT_FAILED, etc, but that's another topic. So I was playing with the program and tried to print out the value of hRunMutex[0] at various points and I found that if I add on extra global variable definition, the whole
problem goes away! That is if I add "char func[10];".
For MAX_THREADS value 3 and above, the program works well with or without that line. But for value 1 and 2, it has to have that
line. Otherwise it gets a currupt handle during execution and could not finish.
I am really curious about the cause of this problem. I'd appreciate if anyone can shed some light on it for me, because besides blaming Microsoft, I am completely clueless. :)
And the reason I am blaming Microsoft is I am using Visual Studio .NET to compile the program. Just create a project with Managed C++ Empty Project, and add this file to project to compile and run it.
Thanks!
Regards, James
/* counters.c file.*/
/* This program will create MAX_THREADS number of threads. Each of them * will increment a shared counter for MAX_COUNT times, sleeping
for a * random number of milliseconds in between each increment. The
main * thread will wait until the shared counter reaches MAX_THREADS*MAX_COUNT. * It will then wait for enter key from input before exiting to
allow * examining the output. */
#include <windows.h> #include <stdio.h> #include <process.h>
#define MAX_THREADS 2 #define MAX_COUNT 3
/* getrandom returns a random number between min and max. */ #define getrandom( min, max ) ((rand() % (int)(((max) + 1) -
(min))) + (min))
int main( void ); /* Thread 1: main */ void CountProc( int * MyID ); /* Threads 2 to MAX_THREADS: Increment the shared counter */ void CheckCounter( void ); /* Function CheckCounter
called by main() */ void WriteMsg( int iThreadNum, int iMyCount, int iTotalCount );
/* Display information */
HANDLE hRunMutex[MAX_THREADS]; /* Notification mutex */ int iThreadNum; /* Number of threads started
*/ HANDLE hCounterMutex; /* Shared counter mutex */ int iSharedCounter; /* Shared counter used by all threads */ int ThreadID[MAX_THREADS]; /* Thread ID for diaplay */ int done[MAX_THREADS] = {0}; /* Array for thread status
*/ char func[10]; // Necessary to make it work for MAX_THREADS =
1 and 2 cases. Microsoft bug?!
int main() /* Thread One */ { /* Create the mutexes and reset thread count. */ int i; iSharedCounter = 0; for(i=0;i< MAX_THREADS;i++) { hRunMutex[i] = CreateMutex( NULL, TRUE, NULL ); /* Set */ } hCounterMutex = CreateMutex( NULL, FALSE, NULL ); /* Cleared */ iThreadNum = 0;
WriteMsg( 0, 0, iSharedCounter );
/* Create the counting threads. */ while( iThreadNum < MAX_THREADS ) { iThreadNum++; ThreadID[iThreadNum] = iThreadNum;
Undefined behaviour. The second time through this loop, you
increment iThreadNum (making it 2) and then attempted to write into an array
beyond its bounds (ThreadID, only has elements 0 and 1).
_beginthread( CountProc, 0, &ThreadID[iThreadNum] ); }
/* Wait until the shared counter reaches the limit. */ CheckCounter(); WriteMsg( 0, 0, iSharedCounter );
/* All threads done. Clean up handles. */ for(i=0;i<MAX_THREADS;i++) { /* if(done[i] != 1) */ CloseHandle( hRunMutex[i] ); } CloseHandle( hCounterMutex);
/* Pause for 10 seconds before exiting */ printf("Press enter to exit..."); getchar(); }
void CheckCounter( void ) /* Check shared counter
*/ { int i;
/* Check the share counter limit, sleep in between each check */ while ( iSharedCounter < MAX_COUNT * MAX_THREADS) { Sleep(getrandom(0,100)); }
/* Wait for the woker threads to exit first */ while ( iThreadNum > 0 ) { for(i = 0;i<MAX_THREADS;i++) { if(done[i] == 0 ) { int ret = WaitForSingleObject( hRunMutex[i], 100 ); if(ret == WAIT_OBJECT_0 /*|| ret == WAIT_FAILED*/) { iThreadNum--; done[i]=ret+2; } } } Sleep(getrandom(0,100)); } }
void CountProc( int *MyID ) { int i=0; do { /* Wait for counter to be available, then lock it. */ WaitForSingleObject( hCounterMutex, INFINITE ); iSharedCounter++; WriteMsg(*MyID, i, iSharedCounter); ReleaseMutex( hCounterMutex );
i++; Sleep(getrandom(0, 5)); } while(i < MAX_COUNT);
ReleaseMutex( hRunMutex[(*MyID)-1] ); }
void WriteMsg( int iThreadNum, int iMyCount, int iTotalCount ) { printf("Thread ID: %d, Local Count: %d, Shared Count: %d \n", iThreadNum, iMyCount, iTotalCount ); }
This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Vinay |
last post by:
Hi
I have a corrupt word file. I am able to open it with the code given below
tr
Dim pInfo As System.Diagnostics.ProcessStartInfo = New...
|
by: Jeffrey Baker |
last post by:
Hi,
I am recompiling a program from VC++ 5.0 to VC++.NET interface. C++
Compliance is tighter. I get the
error message before the program finished...
|
by: Eric E |
last post by:
Hi all,
I have a fairly complex form in Access 2000. In particular, it has two
subforms on separate tabs of a tab control. For the last two...
|
by: Joseph Macari |
last post by:
I recently installed Office2003 on my computer. I had imported (not linked)
a couple of tables from an Access 2000mdb into an Access 2003mdb. I had...
|
by: Default |
last post by:
Hi, I am new to C#, that is why I am not sure what kind of problem it is: Is
VS files corrupted , or something else. that is the problems...
|
by: Mongoose7 |
last post by:
Hi,
I am using vc7 to call a dll function from another dll. The function
seems to execute correctly (it writes binary data to the registry) but...
|
by: WoodenSWord |
last post by:
Hello i would like to share with you my adventure!!!
IIS could not load aspx or asmx pages by NO Means!
I reinstalled/unistalled/installed IIS...
|
by: Jeff |
last post by:
Okay, I'm still new to vb.net 2005 - throught this was a hardware problem,
but now I don't know.
(I'm having some problem with my newgroup...
|
by: danep2 |
last post by:
Hello all
This is a really strange problem. I have code that performs a few
calculations based on input from a joystick, and writes these values...
|
by: Kemmylinns12 |
last post by:
Blockchain technology has emerged as a transformative force in the business world, offering unprecedented opportunities for innovation and...
|
by: jalbright99669 |
last post by:
Am having a bit of a time with URL Rewrite. I need to incorporate http to https redirect with a reverse proxy. I have the URL Rewrite rules made...
|
by: antdb |
last post by:
Ⅰ. Advantage of AntDB: hyper-convergence + streaming processing engine
In the overall architecture, a new "hyper-convergence" concept was...
|
by: Matthew3360 |
last post by:
Hi there. I have been struggling to find out how to use a variable as my location in my header redirect function.
Here is my code.
...
|
by: AndyPSV |
last post by:
HOW CAN I CREATE AN AI with an .executable file that would suck all files in the folder and on my computerHOW CAN I CREATE AN AI with an .executable...
|
by: WisdomUfot |
last post by:
It's an interesting question you've got about how Gmail hides the HTTP referrer when a link in an email is clicked. While I don't have the specific...
|
by: Matthew3360 |
last post by:
Hi,
I have been trying to connect to a local host using php curl. But I am finding it hard to do this. I am doing the curl get request from my web...
|
by: Carina712 |
last post by:
Setting background colors for Excel documents can help to improve the visual appeal of the document and make it easier to read and understand....
|
by: BLUEPANDA |
last post by:
At BluePanda Dev, we're passionate about building high-quality software and sharing our knowledge with the community. That's why we've created a SaaS...
| |