我正在尝试创建一个类的 12 个新实例并运行它们中的每一个,它是一个自己的线程,但它们会共享相同的数据。所有 12 个实例都在相同的 X 和 Y 位置,但它们每个都应该在随机方向上移动。正如您在代码中看到的那样,我尝试了各种 apraoches,但我无法找出原因。
我在这里做错了什么?
ps是的...我知道还有一些未使用的变量。pss 在我发布问题之前,我已经看过很多地方和这里
敌人.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
}
敌人.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;
};