采用CreateThread()创建多线程程序

本文详细介绍了在Windows环境下如何使用CreateThread API创建和管理多线程,包括线程函数定义、多线程实例及注意事项。通过示例展示了多线程在界面更新和协同工作中的应用,强调了线程参数传递、线程函数类型和线程同步的重要性。
摘要由CSDN通过智能技术生成

采用CreateThread()创建多线程程序

在window环境下,Win32 提供了一系列的API函数来完成线程的创建、挂起、恢复、终结以及通信等工作:

1、主要的函数列表:

序号

函数名

功能

1

CreateThread()

创建一个新线程

2

ExitThread()

正常结束一个线程的执行

3

TerminateThead()

强制终止一个线程的执行

4

ResumeThread()

重启一个线程

5

SuspendThread()

挂起一个线程

6

GetExiCodeThread()

得到一个线程的退出码

7

GetThreadPriority()

得到一个线程的优先级

8

SetThreadPriority()

设置一个线程的优先级

9

CloseHandle()

关闭一个线程的句柄

10

CreateRemoteThread()

再另一个进程中创建一个新线程

11

PostThreadMessage()

发送一条消息给指定的线程

12

GetCurrentThread()

得到当前的线程句柄

13

GetCurrentThreadId()

得到当前线程的ID

14

GetThreadId()

得到指定线程的ID

15

WaitForSingleObject()

等待单个对象

16

WaitForMultipleObjects()

等待多个对象

关于多线程的API函数还有很多,以上只是列出了一些比较常用的函数,欲知更多函数和函数的使用方法,请参考MSDN或网络资源,在此就不再介绍了。

2、线程函数的定义:

线程函数的规范格式定义为

DWORD  WINAPI ThreadProc (LPVOID lpParam);//格式不正确将无法调用成功。函数名称没有限制,只要符合命名规则就可以。

但我常常看到有下列的线程函数定义:

void ThreadProc ();//该格式也是可以的,但使用的时候要这样通过

LPTHREAD_START_ROUTINE转换,如:

(LPTHREAD_START_ROUTINE)ThreadProc

我建议还是使用规范的格式比较好,不推荐使用void ThreadProc ()格式。不信就请看看MSDN的说明吧:

Do not declare this callback function with a void return typeand cast the function pointer to LPTHREAD_START_ROUTINE when creatingthe thread. Code that does this is common, but it can crash on 64-bit Windows.

而且线程函数必须是全局函数,不能在类中声明和定义。

3、多线程实例1:

我在此将写一个简单的多线程程序,用以展示多线程的功能和使用方法。该程序的主要的思想是画3个进度条,分别以多线程和单线程方式完成,大家可以比较一下。

说明:

(1)该程序还将和单线程做对比。

(2)由于给线程的函数传递了多个参数,所以采用结构体的方式传递参数。

(3)为了演示效果,采用了比较耗时的打点处理。

主要的函数如下:

在头文件的定义

//线程函数声明
DWORD WINAPI ThreadProc(LPVOIDlpParam);
//为了传递多个参数,我采用结构体
struct threadInfo
{
    HWND hWnd;       //窗口句柄
    int  nOffset;    //偏移量
    COLORREF clrRGB; //颜色
};
 
protected:
HANDLE hThead[3];    //用于存储线程句柄
    DWORD  dwThreadID[3];//用于存储线程的ID
  threadInfo Info[3];   //传递给线程处理函数的参数


//实现文件中

//单线程测试
void CMultiThread_1Dlg::OnBnClickedButton1()
{
    // TODO: 在此添加控件通知处理程序代码
    //使能按钮
    GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE);
    GetDlgItem(IDC_BUTTON2)->EnableWindow(FALSE);
    CDC *dc = GetDC();
    CRect rt;
    GetClientRect(rt);
    dc->FillSolidRect(0,0,rt.Width(),rt.Height()-70,RGB(240,240,240));//刷新背景
    dc->TextOut(97,470,"#1");
    dc->TextOut(297,470,"#2");
    dc->TextOut(497,470,"#3");
    //#1
    for (int i=0;i<460;i++)
    {
       for (int j =10 ;j<200;j++)
       {
           dc->SetPixel(j,460-i,RGB(255,0,0));
       }
    }
    //#2
    for (int i=0;i<460;i++)
    {
       for (int j =210 ;j<400;j++)
        {
           dc->SetPixel(j,460-i,RGB(0,255,0));
       }
    }
    //#3
    for (int i=0;i<460;i++)
    {
       for (int j =410 ;j<600;j++)
       {
           dc->SetPixel(j,460-i,RGB(0,0,255));
       }
    }
    ReleaseDC(dc);
    //使能按钮
    GetDlgItem(IDC_BUTTON1)->EnableWindow(TRUE);
    GetDlgItem(IDC_BUTTON2)->EnableWindow(TRUE);
}
 
//多线程测试
void CMultiThread_1Dlg::OnBnClickedButton2()
{
    // TODO: 在此添加控件通知处理程序代码
    CDC *dc = GetDC();
    CRect rt;
    GetClientRect(rt);
    dc->FillSolidRect(0,0,rt.Width(),rt.Height()-70,RGB(240,240,240));//刷新背景
    dc->TextOut(97,470,"#1");
    dc->TextOut(297,470,"#2");
    dc->TextOut(497,470,"#3");
    //初始化线程的参数
    Info[0].hWnd = Info[1].hWnd = Info[2].hWnd = GetSafeHwnd();
    Info[0].nOffset = 10;Info[1].nOffset = 210;Info[2].nOffset = 410;
    Info[0].clrRGB = RGB(255,0,0);Info[1].clrRGB= RGB(0,255,0);Info[2].clrRGB = RGB(0,0,255);
    //创建线程
    for (int i = 0;i<3;i++)
    {
       hThead[i] = CreateThread(NULL,0,ThreadProc,&Info[i],0,&dwThreadID[i]);
    }
    ReleaseDC(dc);
}
 
DWORD WINAPI ThreadProc(LPVOIDlpParam)
{
    threadInfo*Info = (threadInfo*)lpParam;
    CDC *dc = CWnd::FromHandle(Info->hWnd)->GetDC();
    for (int i=0;i<460;i++)
    {
       for (int j=Info->nOffset;j<Info->nOffset+190;j++)
       {
           dc->SetPixel(j,460-i,Info->clrRGB);
       }
    }
    DeleteObject(dc);
    return 0;
}


运行效果:

单线程测试


多线程测试

工程源码下载地址:

http://download.csdn.net/detail/cbnotes/4857152

欢迎大家修改和指正。

注意事项:

(1)传递给线程执行函数的参数不能是局部变量,而且必须是参数的地址。如:

Int nOffset = 10;

CreateThread(NULL,0,ThreadProc,nOffset,0,&dwThreadID[i]);//错误

CreateThread(NULL,0,ThreadProc,&nOffset,0,&dwThreadID[i]);//错误

Int *pOffset = newint(10);

CreateThread(NULL,0,ThreadProc,pOffset,0,&dwThreadID[i]);//正确

(2)线程执行函数必须是全局函数。

(3)请大家改改下面的程序,且解释下为什么?

这是我开始写程序遇到的一个问题,

改写上面的函数:只是将结构体中一个参数改为CDC指针,以便直接调用。

struct threadInfo

{

    CDC * dc;        //画布

    int  nOffset;    //偏移量

    COLORREF clrRGB; //颜色

};

//多线程测试

  • 51
    点赞
  • 244
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值