pthread windows crash C++ - c++

I would like to create an array of length 50 with a thread, when this is done I would like to print some of the first values in every X seconds with a second thread. In the meanwhile the first thread can compute the next array.
The threads are functional until I try to copy some values from the computed array in some temporary variables. I have no compilation error but when I run the program I get a windows crash massage.
Without threads the double *newarray(); function works. Returns an array which was manually allocated and filled with data.
What am I missing here?
Thread 1:
double *newarray();
void *computingU(void *)
{
double * U_tmp;
while (true)
{
pthread_mutex_lock( &mutexU );
memcpy(U_tmp,newarray(),sizeof(double)*Ulenght);
while (!Usent);
Usent = false;
memcpy(Ucmd,U_tmp,sizeof(double)*Ulenght);
pthread_mutex_unlock( &mutexU );
Ucomputed = true;
}
}
Thread 2:
void *sendingCMD(void * ) {
double * U_tmp;
while (true)
{
while (!Ucomputed);
Ucomputed = false;
pthread_mutex_lock( &mutexU );
memcpy(U_tmp,Ucmd,sizeof(double)*Ulenght);
pthread_mutex_unlock( &mutexU );
Usent = true;
for (int i = 0; i<Ulenght; i++)
{
printf("i= %d, u= %f", i, U_tmp[i]);
sleep(sleepTime) ;
}
}
}
Main:
#include <pthread.h>
#include <time.h>
#include <math.h>
#include <unistd.h>
using namespace std;
bool Ucomputed = false, Usent = true;
double * Ucmd;
pthread_mutex_t mutexU = PTHREAD_MUTEX_INITIALIZER;
unsigned int Ulenght = 1;
int sleepTime = 1;
int main( void )
{
#ifdef DEBUG_THREAD
int rc1, rc2;
pthread_t thread1, thread2;
/* Create independent threads each of which will execute functionC */
if( (rc1=pthread_create( &thread1, NULL, &computingU, NULL)) ) {
printf("Thread creation failed: %d\n", rc1);
}
if( (rc2=pthread_create( &thread2, NULL, &sendingCMD, NULL)) )
{
printf("Thread creation failed: %d\n", rc2);
}
#endif //
sleep(10);
while (true);
}

Lets take the first thread in the computingU function, there you have a local variable:
double * U_tmp;
Later you use this variable:
memcpy(U_tmp,newarray(),sizeof(double)*Ulenght);
But nowhere do you initialize the variable, so it doesn't point to anything. As uninitialized (non-static) local variables have indeterminate value, so the pointer U_tmp will point to a seemingly random location. Writing there will lead to undefined behavior and most likely your crash.
And you have the same problem in the other thread.

Look at:
double * U_tmp;
You never set the pointer to anything, and then attempt to memcpy() data into it. That will 100% crash every time. If it doesn't your OS is broken.

Related

Call join child pthread in main function

I have the test code:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
pthread_t th_worker, th_worker2;
void * worker2(void *data) {
for(int i = 0; i< 1000000; i++){
printf("thread for worker2----%d\n", i);
usleep(500);
}
}
void * worker(void *data){
pthread_create(&th_worker2, NULL, worker2, data);
for(int i = 0; i< 100; i++){
printf("thread for worker-----%d\n", i);
usleep(500);
}
}
void join(pthread_t _th){
pthread_join(_th, NULL);
}
In main() function, If I call join(the_worker2):
int main() {
char* str = "hello thread";
pthread_create(&th_worker, NULL, worker, (void*) str);
/* problem in here */
join(th_worker2);
return 1;
}
--> Segment Fault error
Else, i call:
join(the_worker);
join(th_worker2);
---> OK
Why have segment fault error in above case?
Thanks for help !!!
If you posted all your code, you have a race condition.
main is synchronized with the start of worker but not worker2.
That is, main is trying to join th_worker2 before worker has had a chance to invoke pthread_create and set up th_worker2 with a valid [non-null] value.
So, th_worker2 will be invalid until the second pthread_create completes, but that's already too late for main. It has already fetched th_worker2, which has a NULL value and main will segfault.
When you add the join for th_worker, it works because it guarantees synchronization and no race condition.
To achieve this guarantee without the join, have main do:
int
main()
{
char *str = "hello thread";
pthread_create(&th_worker, NULL, worker, (void *) str);
// give worker enough time to properly start worker2
while (! th_worker2)
usleep(100);
/* problem in here */
join(th_worker2);
return 1;
}
An even better way to do this is to add an extra variable. With this, the first loop is not needed [but I've left it in]:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
int worker_running;
pthread_t th_worker;
int worker2_running;
pthread_t th_worker2;
void *
worker2(void *data)
{
// tell main we're fully functional
worker2_running = 1;
for (int i = 0; i < 1000000; i++) {
printf("thread for worker2----%d\n", i);
usleep(500);
}
return NULL;
}
void *
worker(void *data)
{
// tell main we're fully functional
worker_running = 1;
pthread_create(&th_worker2, NULL, worker2, data);
for (int i = 0; i < 100; i++) {
printf("thread for worker-----%d\n", i);
usleep(500);
}
return NULL;
}
void
join(pthread_t _th)
{
pthread_join(_th, NULL);
}
int
main()
{
char *str = "hello thread";
pthread_create(&th_worker, NULL, worker, (void *) str);
// give worker enough time to properly start worker2
// NOTE: this not necessarily needed as loop below is better
while (! th_worker2)
usleep(100);
// give worker2 enough time to completely start
while (! worker2_running)
usleep(100);
/* problem in here (not anymore!) */
join(th_worker2);
return 1;
}

Dead lock pthread C++ with signaling

I need 2 threads: TC and TS, such that they are composed in two main sections each accessing shared data and the threads must to be synchronized. The synchronization should be like this:
The red codes are working with shared data U, but get U can be placed before the dashed rectangle on the TS thread, riht side.
The Xcurrent can be in TC or in TS the tasks, but is a shared hardware with send Ucurrent and get must be right after send was finished.
A dead lock appears and I can't figure out an elegant solution.
Thread TS:
#include <stdio.h> /* printf, scanf, NULL */
#include <stdlib.h> /* malloc, free, rand */
#define _USE_MATH_DEFINES
#include <math.h>
#include <windows.h>
#include <pthread.h>
#include <time.h>
// CRLT-C var
static int stop = 0;
// TIMEING vars
__int64 frequencyT, startT, endT = 0;
double baseAngleLast;
double pendulAngleLast;
// THREADING vars
bool startedS = false, Usent = false;
double * Ucmd;
pthread_mutex_t mutexU = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutexBoard = PTHREAD_MUTEX_INITIALIZER;
unsigned int Ulenght = 6;
pthread_cond_t signal_to_read_state = PTHREAD_COND_INITIALIZER;
pthread_cond_t signal_to_read_cmd = PTHREAD_COND_INITIALIZER;
DWORD sleepTime = 30; // in milliseconds
int currentState = 3;
void *sendingCMD(void * )
{
double * U_tmp;
U_tmp = (double*)malloc(sizeof(double)*Ulenght);
startedS = true;
printf("Sin\n");
while (stop == 0)
{
printf("Smu-\n");
//get U
pthread_mutex_lock( &mutexU );
printf("Smu..\n");
pthread_cond_wait(&signal_to_read_cmd, &mutexU);
memcpy(U_tmp,Ucmd,sizeof(double)*Ulenght);
pthread_mutex_unlock( &mutexU );
printf("Smu+\n");
pthread_mutex_lock( &mutexBoard );
for (unsigned int i = 0; i<Ulenght; i++)
{
//send CMD signal
printf("%f ", U_tmp[i]);
if (i == Ulenght -1) printf("\n");
}
Sleep(sleepTime); // miliseconds
currentState = currentState + 1;
pthread_cond_signal(&signal_to_read_state);
pthread_mutex_unlock( &mutexBoard );
printf("Smb\n");
}
printf("Task S terminated. \n");
return (NULL);
}
void *computingU(void *)
{
double * U_tmp;
U_tmp = (double*)malloc(sizeof(double)*Ulenght);
int currentStateTMP =0;
bool fisrtLoop = true;
printf("Uin\n");
while (stop == 0)
{
printf("Umb- \n");
// get current state
pthread_mutex_lock( &mutexBoard );
if (!fisrtLoop)
{
printf("UmbFalse \n");
pthread_cond_wait(&signal_to_read_state, &mutexBoard);
}
else
{
printf("UmbTrue \n");
fisrtLoop=false;
}
currentStateTMP =currentState;
pthread_mutex_unlock( &mutexBoard );
printf("Umb+ \n");
pthread_mutex_lock( &mutexU );
for (unsigned int i=0;i<Ulenght;i++)
{
Ucmd[i] = Ucmd[i]+ (double)currentStateTMP/i;
}
pthread_cond_signal(&signal_to_read_cmd);
pthread_mutex_unlock( &mutexU );
printf("Umu\n");
}
return (NULL);
}
void signal_handler(int signal)
{
stop = 1;
}
int main(int argc, char* argv[])
{
//initializing output buffer to 0[V]
Ucmd= (double*)malloc(sizeof(double)*Ulenght);
for (unsigned int i=0;i<Ulenght;i++)
Ucmd[i] = 0;
//init threads
int rc1, rc2;
pthread_t threadU, threadS;
/* Create independent threads each of which will execute functionC */
if( (rc1=pthread_create( &threadU, NULL, &computingU, NULL)) ) {
printf("ThreadU creation failed: %d\n", rc1);
}
if( (rc2=pthread_create( &threadS, NULL, &sendingCMD, NULL)) )
{
printf("ThreadS creation failed: %d\n", rc2);
}
while (stop == 0);
printf("Main terminated, closing board in 10ms. \n");
Sleep(10);
return 0;
}
The blocking appears at:
TC at pthread_cond_wait(&signal_to_read_state, &mutexBoard);
TS at pthread_cond_wait(&signal_to_read_cmd, &mutexU);
btw why dose not recognize stackoverflow the code segment I pasted above in case i copy paste from a VS2010?

Idea Behind Recursive Mutex Lock

I'm working on a school lab and we are instructed to create a recursive mutex lock for a counting program. I've written some code (which doesn't work), but I think that this is mostly because I do not understand the real idea behind using a recursive mutex lock. Could anyone elaborate what a recursive mutex lock should do/look like?
General Note: I'm not asking for an answer, just some clarification as to what recursive mutex lock should do.
Also, if anyone is curious, here is the code required for this. The code that I am editing/implementing is the recmutex.c.
recmutex.h
#include <pthread.h>
/*
* The recursive_mutex structure.
*/
struct recursive_mutex {
pthread_cond_t cond;
pthread_mutex_t mutex; //a non-recursive pthread mutex
pthread_t owner;
unsigned int count;
unsigned int wait_count;
};
typedef struct recursive_mutex recursive_mutex_t;
/* Initialize the recursive mutex object.
*Return a non-zero integer if errors occur.
*/
int recursive_mutex_init (recursive_mutex_t *mu);
/* Destroy the recursive mutex object.
*Return a non-zero integer if errors occur.
*/
int recursive_mutex_destroy (recursive_mutex_t *mu);
/* The recursive mutex object referenced by mu shall be
locked by calling pthread_mutex_lock(). When a thread
successfully acquires a mutex for the first time,
the lock count shall be set to one and successfully return.
Every time a thread relocks this mutex, the lock count
shall be incremented by one and return success immediately.
And any other calling thread can only wait on the conditional
variable until being waked up. Return a non-zero integer if errors occur.
*/
int recursive_mutex_lock (recursive_mutex_t *mu);
/* The recursive_mutex_unlock() function shall release the
recursive mutex object referenced by mu. Each time the owner
thread unlocks the mutex, the lock count shall be decremented by one.
When the lock count reaches zero, the mutex shall become available
for other threads to acquire. If a thread attempts to unlock a
mutex that it has not locked or a mutex which is unlocked,
an error shall be returned. Return a non-zero integer if errors occur.
*/
int recursive_mutex_unlock (recursive_mutex_t *mu);
recmutex.c: contains the functions for the recursive mutex
#include <stdio.h>
#include <pthread.h>
#include <errno.h>
#include "recmutex.h"
int recursive_mutex_init (recursive_mutex_t *mu){
int err;
err = pthread_mutex_init(&mu->mutex, NULL);
if(err != 0){
perror("pthread_mutex_init");
return -1;
}else{
return 0;
}
return 0;
}
int recursive_mutex_destroy (recursive_mutex_t *mu){
int err;
err = pthread_mutex_destroy(&mu->mutex);
if(err != 0){
perror("pthread_mutex_destroy");
return -1;
}else{
return 1;
}
return 0;
}
int recursive_mutex_lock (recursive_mutex_t *mu){
if(mutex_lock_count == 0){
pthread_mutex_lock(&mu->mutex);
mu->count++;
mu->owner = pthread_self();
printf("%s", mu->owner);
return 0;
}else if(mutex_lock_count > 0){
pthread_mutex_lock(&mu->mutex);
mu->count++;
mu->owner = pthread_self();
return 0;
}else{
perror("Counter decremented incorrectly");
return -1;
}
}
int recursive_mutex_unlock (recursive_mutex_t *mu){
if(mutex_lock_count <= 0){
printf("Nothing to unlock");
return -1;
}else{
mutex_lock_count--;
pthread_mutex_unlock(&mu->mutex);
return 0;
}
}
count_recursive.cc: The counting program mentioned above. Uses the recmutex functions.
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>
#include <assert.h>
#include <string.h>
#include "recmutex.h"
//argument structure for the thread
typedef struct _arg_{
int n1;
int n2;
int ntimes;
}Arg;
int count; //global counter
recursive_mutex_t mutex; //the recursive mutex
void do_inc(int n){
int ret;
if(n == 0){
return;
}else{
int c;
ret = recursive_mutex_lock(&mutex);
assert(ret == 0);
c = count;
c = c + 1;
count = c;
do_inc(n - 1);
ret = recursive_mutex_unlock(&mutex);
assert(ret == 0);
}
}
/* Counter increment function. It will increase the counter by n1 * n2 * ntimes. */
void inc(void *arg){
Arg * a = (Arg *)arg;
for(int i = 0; i < a->n1; i++){
for(int j = 0; j < a->n2; j++){
do_inc(a->ntimes);
}
}
}
int isPositiveInteger (const char * s)
{
if (s == NULL || *s == '\0' || isspace(*s))
return 0;
char * p;
int ret = strtol (s, &p, 10);
if(*p == '\0' && ret > 0)
return 1;
else
return 0;
}
int test1(char **argv){
printf("==========================Test 1===========================\n");
int ret;
//Get the arguments from the command line.
int num_threads = atoi(argv[1]); //The number of threads to be created.
int n1 = atoi(argv[2]); //The outer loop count of the inc function.
int n2 = atoi(argv[3]); //The inner loop count of the inc function.
int ntimes = atoi(argv[4]); //The number of increments to be performed in the do_inc function.
pthread_t *th_pool = new pthread_t[num_threads];
pthread_attr_t attr;
pthread_attr_init( &attr );
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
ret = recursive_mutex_init(&mutex);
assert(ret == 0);
printf("Start Test. Final count should be %d\n", num_threads * n1 * n2 * ntimes );
// Create threads
for(int i = 0; i < num_threads; i++){
Arg *arg = (Arg *)malloc(sizeof(Arg));
arg->n1 = n1;
arg->n2 = n2;
arg->ntimes = ntimes;
ret = pthread_create(&(th_pool[i]), &attr, (void * (*)(void *)) inc, (void *)arg);
assert(ret == 0);
}
// Wait until threads are done
for(int i = 0; i < num_threads; i++){
ret = pthread_join(th_pool[i], NULL);
assert(ret == 0);
}
if ( count != num_threads * n1 * n2 * ntimes) {
printf("\n****** Error. Final count is %d\n", count );
printf("****** It should be %d\n", num_threads * n1 * n2 * ntimes );
}
else {
printf("\n>>>>>> O.K. Final count is %d\n", count );
}
ret = recursive_mutex_destroy(&mutex);
assert(ret == 0);
delete [] th_pool;
return 0;
}
int foo(){
int ret;
printf("Function foo\n");
ret = recursive_mutex_unlock(&mutex);
assert(ret != 0);
return ret;
}
//test a thread call unlock without actually holding it.
int test2(){
int ret;
printf("\n==========================Test 2==========================\n");
pthread_t th;
pthread_attr_t attr;
pthread_attr_init( &attr );
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
ret = recursive_mutex_init(&mutex);
ret = pthread_create(&th, &attr, (void * (*)(void *))foo, NULL);
printf("Waiting for thread to finish\n");
ret = pthread_join(th, NULL);
assert(ret == 0);
return 0;
}
int main( int argc, char ** argv )
{
int ret;
count = 0;
if( argc != 5 ) {
printf("You must enter 4 arguments. \nUsage: ./count_recursive num_threads n1 n2 ntimes\n");
return -1;
}
if(isPositiveInteger(argv[1]) != 1 || isPositiveInteger(argv[2]) != 1 || isPositiveInteger(argv[3]) != 1 || isPositiveInteger(argv[4]) != 1 ){
printf("All the 4 arguments must be positive integers\n");
return -1;
}
test1(argv);
test2();
return 0;
}
The idea of a recursive mutex is that it can be successfully relocked by the thread that is currently holding the lock. For example:
if I had some mutexes like this (this is pseudocode):
mutex l;
recursive_mutex r;
In a single thread if I did this:
l.lock();
l.lock(); // this would hang the thread.
but
r.lock();
r.lock();
r.lock(); // this would all pass though with no issue.
In implimenting a recursive mutex you need to check what threadId has locked it, if it was locked, and if it matches the current thread id, return success.
The point of a recursive mutex, is to let you write this:
recursive_mutext_t rmutex;
void foo(...) {
recursive_lock_lock(&rmutex);
...
recursive_lock_unlock(&rmutex);
}
void bar(...) {
recursive_lock_lock(&rmutex);
...
foo(...);
...
recursive_lock_unlock(&rmutex);
}
void baz(...) {
...
foo(...);
...
}
The function foo() needs the mutex to be locked, but you want to be able to call it either from bar() where the same mutex is already locked, or from baz() where the mutex is not locked. If you used an ordinary mutex(), the thread would self-deadlock when foo() is called from bar() because the ordinary mutex lock() function will not return until the mutex is unlocked, and there's no other thread that will unlock it.
Your recursive_mutex_lock() needs to distinguish these cases; (1) The mutex is not locked, (2) the mutex is already locked, but the calling thread is the owner, and (3) the mutex is already locked by some other thread.
Case (3) needs to block the calling thread until the owner completely unlocks the mutex. At that point, it then converts to case (1). Here's a hint: Handle case (3) with a condition variable. That is to say, when the calling thread is not the owner, the calling thread should do a pthread_condition_wait(...) call.

Running multiple objects each on their own thread appears to run the same object multiple times

I'm trying to create 12 new instances of a class and run each of them it's a own thread, but they seam to share the same data.
all 12 instances are on the same X and Y position, but they each should move on a random direction.
as you can see in the code, i tried various apraoches and i can't find out why.
what am i doing wrong here?
p.s. yes ... i know there are still some unused variables.
p.s.s i have looked at many places and also here before i posted the question
enemy.cpp
#include "enemy.h"
#include <time.h>
#include <windows.h>
FILE* pEnemyFile = fopen ("enemylog.txt","w");
Enemy::Enemy(const MouseServer& mServer, int& lastMousePosX, int& lastMousePosY, int& winSizeX, int& winSizeY )
:mouseServer(mServer),
lastMouseX( ( lastMousePosX ) ? lastMousePosX : 0 ), // evaluate if we get the reference
lastMouseY( ( lastMousePosY ) ? lastMousePosY : 0 ),
myPositionX(0),
myPositionY(0),
winSizeX(winSizeX),
winSizeY(winSizeY),
x(0),
y(0)
{
// original source:
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms682516(v=vs.85).aspx
// Allocate memory for thread data.
EDATA threadEnemyData = (EDATA) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,sizeof(enemyData));
// http://www.codeproject.com/Articles/14746/Multithreading-Tutorial
// http://www.codeguru.com/cpp/w-d/dislog/win32/article.php/c9823/Win32-Thread-Synchronization-Part-I-Overview.htm
// usefull information
// http://msdn.microsoft.com/en-us/library/z3x8b09y(v=vs.100).aspx
if( threadEnemyData == NULL )
{
//If the array allocation fails, the system is out of memory
//so there is no point in trying to print an error message.
//Just terminate execution.
ExitProcess(2);
}
threadEnemyData->X = 0;
threadEnemyData->Y = 0;
this->hThread = CreateThread(
NULL,
0,
this->MyThreadFunction,
this,
/*threadEnemyData,*/
0,
&this->dwThreadID
);
// Check the return value for success.
// If CreateThread fails, terminate execution.
// This will automatically clean up threads and memory.
if (this->hThread== NULL)
{
ErrorHandler(TEXT("CreateThread"));
ExitProcess(3);
}
//End of main thread creation loop.
}
Enemy::~Enemy()
{
// Wait until all threads have terminated.
WaitForSingleObject(this->hThread,INFINITE);
// Close all thread handles and free memory allocations.
this->hDefaultProcessHeap = GetProcessHeap();
if (this->hDefaultProcessHeap == NULL) {
}
CloseHandle(this->hThread);
//if(threadEnemyData != NULL)
//{
// HeapFree(GetProcessHeap(), 0, threadEnemyData);
// hThread = NULL; // Ensure address is not reused.
//}
// close debug file
fclose (pEnemyFile);
}
void Enemy::Draw(D3DGraphics& gfx)
{
gfx.PutPixel(this->x + 0,this->y,255,255,255);
gfx.PutPixel(this->x + 1,this->y,255,255,255);
gfx.PutPixel(this->x + 2,this->y,255,255,255);
gfx.PutPixel(this->x + 3,this->y,255,255,255);
gfx.PutPixel(this->x + 4,this->y,255,255,255);
gfx.PutPixel(this->x + 5,this->y,255,255,255);
gfx.PutPixel(this->x + 6,this->y,255,255,255);
gfx.PutPixel(this->x + 7,this->y,255,255,255);
}
// read
// http://www.tek-tips.com/viewthread.cfm?qid=1068278
DWORD WINAPI Enemy::MyThreadFunction( void* param )
{
Enemy* self = (Enemy*) param;
////self-> // <-- "this"
return self->NewThread();
}
/* initialize random seed: */
// the itelligence loop of your enemy/object
DWORD Enemy::NewThread()
{
do
{
srand ( time(NULL) );
/* generate random number: */
//self->x += rand() % 4;
//self->y += rand() % 4;
this->x += rand() % 4;
this->y += rand() % 4;
// debug stuff
char buffer[ 64 ];
sprintf_s(buffer, "enemy: x: %d Y: %d id: %d\n", (char)this->x, (char)this->y, (char)this->dwThreadID);
fputs (buffer,pEnemyFile);
// allow processor time to other threads
Sleep(100);
}while(true); // endles loop
}
void Enemy::ErrorHandler(LPTSTR lpszFunction)
{
// Retrieve the system error message for the last-error code.
this->dw = GetLastError();
// todo
}
enemy.h
#pragma once
#include "timer.h"
#include "D3DGraphics.h"
#include "D3DGraphics.h"
#include "Mouse.h"
/////// thread stuf
#include <tchar.h>
#include <strsafe.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
class Enemy
{
public:
Enemy();
Enemy(const MouseServer& mServer, int& lastMousePos, int& lastMousePosY, int& winSizeX, int& winSizeY);
~Enemy();
static DWORD WINAPI MyThreadFunction( LPVOID lpParam );
DWORD Enemy::NewThread();
void ErrorHandler(LPTSTR lpszFunction);
void lookingForFood();
void Draw(D3DGraphics& gfx);
int Enemy::correctX(int xParam);
int Enemy::correctY(int yParam);
private:
int myPositionX;
int myPositionY;
int lastMouseX;
int lastMouseY;
int winSizeX;
int winSizeY;
//int moveToX; // todo
//int moveToY;
int x;
int y;
// threading stuff
typedef struct ENEMYDATA // don't forget "typedef "
{
int X;
int Y; // test
} enemyData, *EDATA;
// Cast the parameter to the correct data type.
// The pointer is known to be valid because
// it was checked for NULL before the thread was created.
static Enemy* self;
HANDLE hThread;
DWORD dwThreadID;
HANDLE hDefaultProcessHeap;
DWORD dw; // error message
EDATA* threadEnemyData;
MouseClient mouseServer;
//D3DGraphics& grafix;
Timer timer;
};
It's commented out in your thread proc, but looks like you were on the right track:
srand ( time(NULL) );
It didn't work for you because all the threads start so fast that they end up with time(NULL) returning the same value for each thread. This means they're all using the same random sequence. Try seeding rand with the thread ID (or some other source that's unique per thread) and you should see unique pseudorandom number sequences.

Why the compiler is complaining here when apparently there is no error?

Whenever I try to compile the following program, I get this message from the compiler (g++ 4.4.3). Any idea, why?
main.cpp: In function ‘int main(int, char**)’:
main.cpp:52: error: void value not ignored as it ought to be
Line 52 has the code rc = pthread_create_with_stack( &thread[t], BusyWork, t );
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define NUM_THREADS 4
void *stackAddr[NUM_THREADS];
pthread_t thread[NUM_THREADS];
pthread_attr_t attr;
void *BusyWork(void *t)
{
int i;
long tid;
double result=0.0;
tid = (long)t;
printf("Thread %ld starting...\n",tid);
for ( i = 0; i < 1000; i++)
{
result = result + sin(i*tid) * tan(i*tid);
}
printf("Thread %ld done. Result = %e\n", tid, result);
pthread_exit((void*) t);
}
void pthread_create_with_stack( pthread_t * pthread, void *(*start_routine) (void *), int tid )
{
const size_t STACKSIZE = 0xC00000; //12582912
int rc;
size_t i;
pid_t pid;
stackAddr[tid] = malloc(STACKSIZE);
pthread_attr_setstack(&attr, stackAddr[tid], STACKSIZE);
rc = pthread_create( pthread, &attr, start_routine, (void*)0 );
}
int main (int argc, char *argv[])
{
int rc;
long t;
void *status;
/* Initialize and set thread detached attribute */
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
for(t=0; t<NUM_THREADS; t++)
{
printf("Main: creating thread %ld\n", t);
// The following line is the line 52, where error occurs
rc = pthread_create_with_stack( &thread[t], BusyWork, t );
if (rc)
{
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
/* Free attribute and wait for the other threads */
pthread_attr_destroy(&attr);
for(t=0; t<NUM_THREADS; t++)
{
rc = pthread_join(thread[t], &status);
if (rc)
{
printf("ERROR; return code from pthread_join() is %d\n", rc);
exit(-1);
}
printf("Main: completed join with thread %ld having a status"
"of %ld\n",t,(long)status);
}
printf("Main: program completed. Exiting.\n");
pthread_exit(NULL);
}
pthread_create_with_stack returns void, yet you're trying to save this void "value" in an int, which is an error.
It's this line
rc = pthread_create_with_stack( &thread[t], BusyWork, t );
Your definition of pthread_create_with_stack is of type void. Should be of type void* and return rc, the result of pthread_create().
Since pthread_create_with_stack is a void function, and it returns nothing in the definition, setting rc to its return value is not only meaningless, it's an error gcc/g++ won't even let you try to compile.
Yes, there is an error. A return type of void means that the function returns no value. You're trying to assign the return value of pthread_create_with_stack to a local variable, but there is no return value to assign.
You should instead declare pthread_create_with-stack as returning an int, and then make it actually return a value:
int pthread_create_with-stack(...)
{
...
return pthread_create(...);
}
You're taking the return value from a void function and trying to assign it to a variable. pthread_create_with_stack doesn't return anything; don't assign it or use it.
Your pthread_create_with_stack is a void function. It doesn't return a value. You can't assign it's result to a variable.
pthread_create_with_stack is defined as returning void.
rc = pthread_create_with_stack( &thread[t], BusyWork, t );
where rc is defined as int is not legal
void simply means "nothing"
N you simply cant save "nothing"!