createthread,createthread传递参数

http://www.itjxue.com  2023-01-20 22:13  来源:未知  点击次数: 

C++ CreateThread函数如何传递this指针作为参数

CreateThread的第三个参数是函数地址,不是调用函数,所以请把第三个参数的后面的括号去掉,直接写成 。。。NULL, 0, CTcpServer::ThreadProc, (void*)。。。

createthread和beginthread的区别

CreateThread、_beginthread和_beginthreadex都是用来启动

线程的,但大家看到oldworm没有提供_beginthread的方式,考试,大提示beginthread是_beginthreadex的功能子

集,虽然_beginthread内部是调用_beginthreadex但他屏蔽了象安全特性这样的功能,所以_beginthread与

CreateThread不是同等级别,_beginthreadex和CreateThread在功能上完全可替代,我们就来比较一下

_beginthreadex与CreateThread!

CRT的函数库在线程出现之前就已经存在,所以原有的CRT不能真正支持线程,这

导致我们在编程的时候有了CRT库的选择,在MSDN中查阅CRT的函数时都有:

Libraries

LIBC.LIB

 Single  thread  static  library,  retail  version

LIBCMT.LIB

 Multithread  static  library,  retail  version

MSVCRT.LIB  Imp

ort

 library  for  MSVCRT.DLL,  retail  version

这样的提示!

对于线程的支持是后来

的事!

这也导致了许多CRT的函数在多线程的情况下必须有特殊的支持,不能简单的使用CreateThread就OK。

大多的

CRT函数都可以在CreateThread线程中使用,看资料说只有signal()函数不可以,会导致进程终止!但可以用并不是说没有问题!

 

 有些CRT的函数象malloc(),  fopen(),  _open(),  strtok(),  ctime(),

 或localtime()等函数需要专门的线程局部存储的数据块,这个数据块通常需要在创建线程的时候就建立,如果使用CreateThread,这个

数据块就没有建立,然后会怎样呢?在这样的线程中还是可以使用这些函数而且没有出错,实际上函数发现这个数据块的指针为空时,会自己建立一个,然后将其与

线程联系在一起,这意味着如果你用CreateThread来创建线程,然后使用这样的函数,会有一块内存在不知不觉中创建,遗憾的是,这些函数并不将其

删除,而CreateThread和ExitThread也无法知道这件事,于是就会有Memory

 Leak,在线程频繁启动的软件中(比如某些服务器软件),迟早会让系统的内存资源耗尽!

_beginthreadex(内部也调用

CreateThread)和_endthreadex就对这个内存块做了处理,所以没有问题!(不会有人故意用CreateThread创建然后用

_endthreadex终止吧,而且线程的终止最好不要显式的调用终止函数,自然退出最好!)

谈到Handle的问

题,_beginthread的对应函数_endthread自动的调用了CloseHandle,而_beginthreadex的对应函数

_endthreadex则没有,所以CloseHandle无论如何都是要调用的不过_endthread可以帮你执行自己不必写,其他两种就需要自己

写!(Jeffrey  Richter强烈推荐尽量不用显式的终止函数,用自然退出的方式,自然退出当然就一定要自己写CloseHandle)。

关于delphi中的 createthread() 函数传递参数的小问题

这种情况可能是i 变量定义在createthread(nil, 0, @test, @i, 0, ID );这句代码的过程里了.比如procedure proc;vari: integer;begini:=100; //由于i是局部变量,所以在下边这一句结束后,局部变量的存在期就结束了//换句话说,传过程后就产生野指针了.createthread(nil, 0, @test, @i, 0, ID );end;正确的做法就是把 i 变量定义成全部变量如下:unit Unit1;interfaceusesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, StdCtrls;typeTForm1 = class(TForm)Button1: TButton;Edit1: TEdit;procedure Button1Click(Sender: TObject);private{ Private declarations }public{ Public declarations }end;varForm1: TForm1;i: Integer;另外还有一点, 使用线程回调函数时一定要加上stdcall,因为默认参数压栈的方式与这个API不兼容.会导致错误.如果只有一个参数或没有参数,就没有问题.在DELPHI使用回调函数时记得在定义处加上stdcall就不会出乱子了.

MFC CreateThread 显示对话框

:就是上面的asserts发生了同时你正在写的是一个多线程程序,那么asserts发生的原因很可能是你将一个C++对象从一个线程传递给另一个线程同时你无意中使用了那个C++对象(only simple inline wrapper functions should be used(抱歉,这一句不会翻译)),实际上线程之间传递CWnd对象应该传递句柄(HWND)。接收线程应该通过CWnd::FromHandle函数通过传递过来的句柄获取CWnd对象(这里准确的来说应该是CWnd对象的指针)。

线程之间传递C++对象是危险的,除非那个对象被设计为以那种方式使用。

由上面我想到一种在工作线程中弹出的对话框的办法:

1. 转递视图类句柄给线程函数:

HWND HView;

…… // 获取视图类句柄

CreateThread(NULL,0,RecvThread, HView

,0,dwThreadId);

2. 在线程函数中通过句柄获取视图类指针,获取数据给视图类发送自定义消息:

DWORD WINAPI RecvThread(LPVOID lpParam)

{

HWND HView = (HWND)lpParam;

CWnd* pMyView = CWnd::FromHandle(HView);

……

pMyView -SendMessage(WM_TASKDLG_MESSAGE,(WPARAM)(str));

…….

}

3. 在视图类自定义一个消息函数OnTaskDlgMessage专门处理WM_TASKDLG_MESSAGE消息用于创建对话框:

LRESULT CInteAView::OnTaskDlgMessage(WPARAM wParam, LPARAM lParam)

{

CAIDlgProductName dlg;

if(dlg.DoModal() == IDOK)

{

……

}

return 0;

}

当然上面将视图类换为框架类也是可以的。上面就我的经验谈了一种从工作线程中弹出对话框的办法,不当之处还请大家指点。

CreateThread()函数每个参数都是什么意思,线程问题帮我都解释一下好么!

HANDLE CreateThread(

LPSECURITY_ATTRIBUTES lpsa,

DWORD cbStack,

LPTHREAD_START_ROUTINE lpStartAddr,

LPVOID lpvThreadParam,

DWORD fdwCreate,

LPDWORD lpIDThread

);

lpsa:线程句柄的安全属性,比如子进程是否可以继承这个线程句柄,一般情况设置为NULL

cbStack:线程栈大小,一般取0表示默认大小

lpStartAddr:线程入口函数 typedef DWORD (__stdcall *LPTHREAD_START_ROUTINE) (

void* lpThreadParameter );在win32程序中默认的调用函数约定就是WINAPI ,__stdcall = WINAPI 。因此你可以声明你的入口函数为:

DWORD WINAPI ThreadProc( void* lpParamete) {//线程中你要做的事情}

lpvThreadParam:就是线程入口函数的参数,就是ThreadProc( void* lpParamete) 的参数

fdwCreate:控制线程创建的标志一般为0,表示线程立即启动。如果你想创建之后把线程挂起来可以传入CREATE_SUSPENDED ,传入这个参数你需要再适当的地方调用ResumeThread 启动线程

lpIDThread:是线程ID返回值,这个用来接收线程返回的ID

写了这么多我还是怕你不懂:

我举个例子吧,我不保证能运行成功,我也没去编译

DWORD WINAPI ThreadProc( void* lpParameter)

{

int *x = (int*)lpParameter;//获得参数的地址

MessageBox(NULL,TEXT("adf"),NULL,MB_OK);

}

DWORD dwThreadID;

int x = 0;

HANDLE hThread = CreateThread(0,0,ThreadProc,(void*)x,0,dwThreadID);

CloseHandle(hThread);

想学习好windows编程MSDN是必须了解的,你居然不知道什么是MSDN,MSDN就是帮助文档,你可以到百度搜一下并把它下载过来,这对你MFC、Windows API、C/C++等很有帮助的

C++多线程函数CreateThread如何使用?

HANDLE WINAPI CreateThread(

__in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes, // 指向SECURITY_ATTRIBUTES 的指针,为新线程指定安全描述

__in SIZE_T dwStackSize, // 初始化线程堆栈尺寸

__in LPTHREAD_START_ROUTINE lpStartAddress, //线程函数所指向的地址 起始函数

__in_opt LPVOID lpParameter, // 给线程函数传递的参数

__in DWORD dwCreationFlags, // 有关线程的标志

__out_opt LPDWORD lpThreadId //系统分配给线程的ID

);

----第一个参数是安全属性,一般设为nil,使用缺省的安全属性。当我们想此线程有另外的子进程时,可改变它的属性。

----第二个参数是线程堆栈尺寸,一般设为0,表示与此应用的堆栈尺寸相同,即主线程与创建的线程一样长度的堆栈。并且其长度会根据需要自动变长。

----第三个参数,也是最重要的一个,是一个指向函数名的指针,但传递时很简单,只需在线程函数名前加上@就可以了。

----第四个参数是你需要向线程函数传递的参数,一般是一个指向结构的指针。不需传递参数时,则这个参数设为nil。

----第五个参数,传入与线程有关的一些标志,如果是CREATE_SUSPENDED,则创建一个挂起的线程,即这个线程本身已创建,它的堆栈也已创建。但这个线程不会被分配给CPU时间,只有当ResumeThread函数被调用后才能执行;当然,也可以调用SuspendThread函数再次挂起线程。要是标志为0,那么一旦建立线程,线程函数就被立即调用。一般传为0即可。

----第六个参数是系统分配给这个线程的唯一的ID标志

// Example.cpp

#include Windows.h

#include iostream

#include string.h

using namespace std;

DWORD WINAPI StartThread(LPVOID iValue)

{

char lszParam[3];

strcpy(lszParam,(char *)iValue);

int iStart = atoi(lszParam);

for(int i=iStart;i=iStart+10;i++)

coutiendl;

return 0;

}

void main()

{

HANDLE hThread1,hThread2;

DWORD dwGenericThread;

char lszThreadParam[3];

strcpy(lszThreadParam,"3");

hThread1 = CreateThread(NULL,0,StartThread,lszThreadParam,0,dwGenericThread);

if(hThread1 == NULL)

{

DWORD dwError = GetLastError();

cout"Error in Creating thread"dwErrorendl ;

return;

}

WaitForSingleObject(hThread1,INFINITE);

//Second thread creation

strcpy(lszThreadParam,"30");

hThread2 = CreateThread(NULL,0,StartThread,lszThreadParam,0,dwGenericThread);

if(hThread1 == NULL)

{

DWORD dwError = GetLastError();

cout"Error in Creating thread"dwErrorendl ;

return;

}

WaitForSingleObject(hThread2,INFINITE);

}

(责任编辑:IT教学网)

更多

相关CorelDraw教程文章

推荐CorelDraw教程文章