求解决方法,创建线程问题

木落 2008-11-07 01:14:41
在一个类中创建多个线程:
DWORD a;
for (i=1;i=ThreadCout;i++) {
CreateThread(NULL,0,&ReadBlock,NULL,0,&a);
}
相关函数:
原本为 DWORD WINAPI DownBlock(HINTERNET Hnd,DWORD StartPos,DWORD EndPos);
后修改为 DWORD WINAPI ReadBlock(PVOID pParam);


但是都出错:
[BCC32 Error] E2034 Cannot convert 'unsigned long (__stdcall * (_closure )(void *))(void *)' to 'unsigned long (__stdcall *)(void *)'
[BCC32 Error] E2342 Type mismatch in parameter 'lpStartAddress' (wanted 'unsigned long (__stdcall *)(void *)', got 'unsigned long (__stdcall * (_closure )(void *))(void *)')

本想使用汇编,强行压到堆栈然后调用CreateThread,
结果发现不能调用汇编:
[BCC32 Error] E2211 Inline assembly not allowed in inline and template functions

开发工具为C++ Builder 2009

不想使用VCL的TThread,求解决办法。
...全文
126 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
木落 2008-11-13
  • 打赏
  • 举报
回复
是的。。。
11楼说的没错,我需要的方法是不可能实现的,
在Delphi,在C++里面都是如此。
收获良多,结贴!
fieldisme 2008-11-11
  • 打赏
  • 举报
回复
我经常使用一种方法,但不知有没有问题,不过我使用中没有问题,就是线程函数写在外面,里面只有二句代码,一句把参数转换成类指针,另一句调用类的某成员函数,这个成员函数写成死循环,在创建线程时,把this指针传给线程函数
僵哥 2008-11-10
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 fy1993hf 的回复:]
很抱歉,这么久都没来看这个帖子。
感谢大家的回答,但是。。
这些东西是可行的,但是无论如何不能放入类中。
给大家提供两种思路:
1. 解决BCB2009中汇编的内嵌问题,强行调用CreateThread
2. 使用TThread类~对这个很陌生,希望能找点资料。

PS:记得当年在Delphi中是没有这个问题的。
甚至连DWORD WINAPI ReadBlock(PVOID pParam);的参数模型都不要求。。
[/Quote]
不要自作聪明.你的程序是在操作系统的管理下运行的,所以必须要遵守相应管理规则.在Win9x系统当中与现在的系统是完全不同的.
dfasri 2008-11-10
  • 打赏
  • 举报
回复
其实, 这个函数是足够让你处理所有事情的

通常, 全局 / 本单元可视 的线程入口

这个函数的声明, 是有一个指针作为参数的.

假如如果某个线程要直接操作到某个类的内部数据, 那么, 只要把类需要使用的东西, 传到一个结构, 或者一个类里面, 然后在线程
里面把指针进行强制变换, 然后就可以操作所有东西的了. 只是要做多一个步骤.
( 如果是要修改类成员的值, 那么采用指针传值到结构, 如果是只是读取值, 那么就采用 Type * const Pointer 这种形式来传值 )

当然, 使用线程的话, 你就得要注意, 如果你是采用线程直接修改类的实例, 那么, 得要注意上锁, 否则错到你发毛

汇编强行压栈是行不通的.

汇编里面, 每种不同声明的函数调用, 都是有相关协议的 : __stdcall, __fastcall, __cdecl 等等这些写在函数名前面的东东.

是一种调用协议, 直接点说: 大家都知道, 汇编的调用, 是没有传参可言的, 是要在调用之前, 把需要用的参数先压到 AX , DX 等等这些寄存器或内存等
然后被调用的函数按这些规则来读取和使用这些参数的, 这些都是要事先约好的.

强行运行CreateThread成功也好, Thread里面调用线程入口的时候, 是照旧是会调用失败, 最坏的情况还会直接导致程序退出.

木落 2008-11-10
  • 打赏
  • 举报
回复
很抱歉,这么久都没来看这个帖子。
感谢大家的回答,但是。。
这些东西是可行的,但是无论如何不能放入类中。
给大家提供两种思路:
1. 解决BCB2009中汇编的内嵌问题,强行调用CreateThread
2. 使用TThread类~对这个很陌生,希望能找点资料。

PS:记得当年在Delphi中是没有这个问题的。
甚至连DWORD WINAPI ReadBlock(PVOID pParam);的参数模型都不要求。。
yuanreid 2008-11-09
  • 打赏
  • 举报
回复
如果需要在线程内执行类方法,可以考虑使用TThread类

我原来做过一个线程池的控件,实现的机制是将类方法的地址和参数通过消息发送给线程池,在线程池内执行。线程池内的线程继承于TThread类。

线程池支持同步执行和异步执行,异步执行支持客户端轮询结果,也支持回调客户端函数。
jxw1987628 2008-11-09
  • 打赏
  • 举报
回复

class TTask
{
public:
TTask(){MessageBox(0,"Construction","information",MB_OK);}
~TTask(){ MessageBox(0,"Destruction","information",MB_OK);};
protected:
static __stdcall unsigned long ThreadFunc(void *pParam=NULL)
{
while(1){
MessageBox(0,"thread function","warning",MB_OK);
}
}
public:
unsigned long Excute(void){
unsigned long ulThreadID =-1;
::CreateThread( 0,0,ThreadFunc,0,0, &ulThreadID );
return ulThreadID;
}
};

///////////////////////////////////////////////////////////////////
TTask* pTask=0;
pTask =new TTask();
if(pTask){
pTask->Excute();
}

/*

同僵哥意见,他已经说过了,线程函数如果是类的成员函数,那么这个成员函数需要是

静态方法才可以。
*/


萧霖 2008-11-09
  • 打赏
  • 举报
回复
来学习,帮顶。
僵哥 2008-11-07
  • 打赏
  • 举报
回复
注意参数类型,createThread需要用静态函数.
DWORD  __stdcall _ReadBlock(void *Param);//声明

class TTask
{
private:
DWORD Threads[499];
DWORD __stdcall ReadBlock(void *Param); //HINTERNET Hnd,DWORD StartPos,DWORD EndPos
public:
TTask(Cardinal ThreadCout)
{
// 将任务分配给各线程
Cardinal i;
for (i=1;i=ThreadCout;i++) {
//CreateThread(NULL,0,&_ReadBlock,NULL,0,&Threads[i]);
}
}
};

DWORD __stdcall _ReadBlock(void *Param)
{
TTask *Task =(TTask *)Param;
return Task->ReadBlock(NULL);
}
木落 2008-11-07
  • 打赏
  • 举报
回复

不限制方法了,这回的要求是能用就好。
最关键的一点为,这个线程要操作类内的数据,因此最好不要独立出来。
木落 2008-11-07
  • 打赏
  • 举报
回复

你的代码是可行的,但是在类中就成为了不可行的。。。
不过还是要感谢你。
class TTask
{
private:
DWORD Threads[499];
DWORD __stdcall ReadBlock(void *Param); //HINTERNET Hnd,DWORD StartPos,DWORD EndPos
public:
TTask(Cardinal ThreadCout)
{
// 将任务分配给各线程
Cardinal i;
for (i=1;i=ThreadCout;i++) {
//CreateThread(NULL,0,&ReadBlock,NULL,0,&Threads[i]);
}
}
};

把代码贴出来,大家帮我看看。
僵哥 2008-11-07
  • 打赏
  • 举报
回复
DWORD __stdcall _thread_proc(void *Param)
{
MessageBox(GetActiveWindow(),"I am a thread!","Message",MB_OK);
return 0;
}

DWORD threadId;
HANDLE thread = CreateThread(NULL,0,_thread_proc /*Address of the thread procedure */,NULL /*Thread Parameter*/,0,&threadId);
CloseHandle(thread);
僵哥 2008-11-07
  • 打赏
  • 举报
回复
如果不想用TThread,那在使用多线程之前就需要设置IsMultiThread = true;

13,825

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧