BCB多线程编程 ( 转载 )

来源:互联网 发布:cf老说我游戏数据异常 编辑:程序博客网 时间:2024/05/18 02:53

BCB多线程编程

大家可能经常听说“线程”这个词汇:网络蚂蚁采用了多线程下载技术、FoxMail采用了多线程收信技术等等,可能有人就会问:什么是线程呢?

一、什么是线程

对于初次接触“线程”这个概念的人来说,会对线程这个概念有点模糊,特别是对线程、进程、程序这三个概念的区别和联系不太清楚,所谓程序,其实就是磁盘上的可执行的文件,只有当它被启动后才成为一个进程;而进程指一个当前装载到内存中的程序;进程不做任何事,它们只是存在,真正从事某项任务的是才是线程

多线程看上去比较复杂和神秘。的确,像线程同步、线程局部存储(TLS)以及相关的内容确实有其复杂的一面。不过,我相信你会很惊讶地发现,在程序中加入线程是那么的简单,甚至与线程同步的内容,诸如临界、互斥也很简单,至少在原理上是这样。

下面就以一个简单的例子来进一步介绍多线程,这个例子演示了如何创建一个简单的线程。

二、一个简单的多线程程序

新建一个项目,在上面加入两个按钮,名为bUseThread和bNoThread,用来选择单线程还是多线程,然后在程序中加入下面的函数:

 

DWORD CALLBACK ThreadFunc(void *p) { HDC DC=GetDC(Form1->Handle); for(int i=0;i<1000000;i++){ String s=i; TextOut(DC,10,10,s.c_str(),s.Length()); } ReleaseDC(Form1->Handle,DC); return 0; }  

 

CALLBACK表示这是一个回调函数,在我们创建线程时需要回调函数,它也可以象普通函数一样被调用。这个函数的功能是在窗口(10,10)的地方显示0——1000000,1000000这个数是为了能看清楚程序运行而设的,你可以依据你机器的速度来修改这个值。

然后,在bNoThread的onClick事件句柄中加入以下代码:

 

 ThreadFunc(0);

 

这就是普通方式来调用前面函数。

然后在bUseThread的onClick事件句柄中加入以下代码:

 

  DWORD ThreadID;   HANDLE hthread=CreateThread(0,0,ThreadFunc,0,0,&ThreadID);   if(hthread==0)       ShowMessage("NO Thread");

 

API函数CreateThread()的功能是创建一个线程,它的函数原型是:

 

HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes,// 安全属性指针 DWORD dwStackSize,// 初始化线程的栈,以字节为单位 LPTHREAD_START_ROUTINE lpStartAddress,// 线程的入口函数 LPVOID lpParameter,// 新线程的参数 DWORD dwCreationFlags,// 设置线程的标志 LPDWORD lpThreadId // 线程的ID号 );

 

其中第一个参数设置成0表示使用默认的安全属性,如果希望子进程能够继承该线程,则需要设置安全属性。要了解更多信息,请参阅WIN32帮助文件中的SECURITY_ATTRIBUTES部分。

第二个参数设置成0表示线程所能使用的栈的大小与应用程序的栈的大小相同,换句话说,主线程和正在创建的线程有同样大小的栈。如果需要的话,栈的大小会自动增加。简而言之,这个参数一般设置成0即可。

lpStartAddress 参数是这个函数最重要的参数,用于指定线程开始运行时要调用的线程函数的名称。线程函数必须具有下列格式:

 

    DWORD CALLBACK ThreadFunc(void *p)

 

lpParameter 是传递给线程函数的参数,也就是上面的void *p,也就是说,可以传递任何类型的参数的指针给回调函数。

dwCreationFlags 用于设置线程的标志,目前唯一可用的是CREATE_SUSPENDED,创建一个挂起的线程。

lpThreadId 是一个DWORD的指针,当线程创建成功时,用这个参数返回线程的ID。

运行程序可以看出,在使用多线程时,程序在计数时你可以移动窗口,改变窗口大小等,而不使用多线程时,在计数的同时是不能够改变窗口大小和移动窗口的,不信你就在分别单击两个按钮后把鼠标移动到窗口边缘试试。

原创粉丝点击