MFC 多线程编程总结

本文详细总结了MFC中的多线程编程,包括进程与线程的区别、线程创建的三种方式(CreateThread、AfxBeginThread、_beginthreadex)、线程通信方法(全局变量、消息传递、参数传递、线程同步)以及线程同步技术(临界区、事件、互斥对象、信号量)。通过对这些概念和方法的解析,帮助开发者理解和掌握MFC多线程编程的关键知识点。
摘要由CSDN通过智能技术生成
MFC 多线程编程总结

************ 写在前面*************

虽然用过多线程写过一些小软件,但是时间一长就忘记了。所以本着“好记性不如烂笔头”的原则,写这么一篇博客当做复习笔记,看自己写的东西的目录就能想起来。可能会有错误和不足,欢迎大家指正,共同进步。

1、进程与线程

1.1、进程

进程是什么?首先先了解一下程序是什么?
程序是一堆指定的有序集合,本身没有任何运行的含义,是一个静态的实体。而进程是一个程序在一个数据集上的一次执行活动。它是一个动态的实体,有自己的生命周期。创建时产生,调度时运行,等待资源或事件时等待,完成任务时被销毁,这反应了一个进程在一定的数据集运行的全部动态过程。
进程是进行资源申请和调度的基本单位 。

1.2、线程

线程是进程的一个可执行单元,是进程中的一个实体,是进行CPU申请和分配的基本单位。

1.3、进程与线程的区别(常见面试题)

  1. 进程是资源申请和分配的基本单位,线程是CPU申请和调度的基本单位。
  2. 进程和线程是一对多的关系,一个进程至少有一个线程,称为主线程。这个主线程退出,则整个程序也就退出了。
  3. 多个进程之间是逻辑独立的关系,各有各的资源和内存空间。在操作系统正常的情况下,一个进程的崩溃不会影响到另一个进程的运行
  4. (同一个进程内的)多个线程之间是共享该进程的所有资源。
  5. 线程创建和切换较进程所需代价要小。
  6. 多进程程序更加安全,原因是第3点。
  7. 多线程程序的好处?(为什么要引入多线程?)1)提供更好的资源利用率。比如 线程A在用CPU计算,线程B在使用I/O读取文件,这就同时在使用两种资源,如果是单一线程,同一时刻只能使用一种资源;2)更快的响应速度。比如服务器需要监听请求,当请求到达之后,如果处理时间过长,就无法即时监听新的请求。如果是多线程,线程A用来监听请求,然后转发给线程B,之后立即继续监听,线程B只用来处理请求一个线程。这样就保证了服务器能够快速返回监听。就能够有更多的客户端发送请求到服务端,而服务器变得更加及时的响应。

2、线程创建的三种方式

MFC中有三种创建线程的方式,如下:

2.1、CreateThread(需要手动关闭线程句柄)

  1. 函数原型为:
    HANDLE CreateThread(
    LPSECURITY_ATTRIBUTES lpThreadAttributes,
    SIZE_T dwStackSize,
    LPTHREAD_START_ROUTINE lpStartAddress,
    LPVOID lpParameter,
    DWORD dwCreationFlags,
    LPDWORD lpThreadId
    );
  2. 参数说明:
    -参数一参数:线程安全属性,一般默认为NULL
    -参数二参数:线程栈空间的大小,为0时默认为1MB
    -参数三参数:线程函数地址(需要该线程做什么事,就写在此函数中),声明:DWORD WINAPI ThreadFunc(LPVOID pParam)
    -参数四参数:线程函数的参数,指针类型(多个参数可以用结构体或者类打包传递)
    -参数五参数:线程是否立即运行,为0表示线程创建之后立即就可以进行调度,如果为CREATE_SUSPENDED(创建时挂起)则表示线程创建后暂停运行,这样它就无法调度,直到调用ResumeThread()
    -参数六参数:线程ID,创建成功之后该参数返回线程ID,可NULL
    -线程创建成功返回新线程的句柄,失败返回NULL

例子:

#include <iostream>
#include <windows.h>
using namespace std;

DWORD WINAPI ThreadFunc(LPVOID pParam)
{
	cout << "子线程" << endl;
	return 0;
}

int main() 
{
	HANDLE hThread = CreateThread(NULL, 0, ThreadFunc, 0, 0, 0);
	Sleep(2000);
	CloseHandle(hThread);
}

2.2、AfxBeginThread(会自动释放)

MFC提供了两个重载版本的AfxBeginThread,一个用于用户界面线程,一个用于工作者线程。

2.2.1、用户界面线程
  1. 函数原型:
    CWinThread* AfxBeginThread(
    CRuntimeClass* pThreadClass,
    int nPriority,
    UINT nStackSize,
    DWORD dwCreateFlags,
    LPSECURITY_ATTRIBUTES lpSecurityAttrs
    );
  2. 参数说明:
    -参数一参数:从CWinThread派生的RUNTIME_CLASS类
    -参数二参数:线程优先级
    -参数三参数:线程栈空间的大小,为0时默认为1MB
    -参数四参数:线程是否立即运行,为0表示线程创建之后立即就可以进行调度,如果为CREATE_SUSPENDED(创建时挂起)则表示线程创建后暂停运行,这样它就无法调度,直到调用ResumeThread()
    -参数五参数:线程安全属性,一般默认为NULL
    -线程创建成功返回CWinThread*,失败返回NULL
    一般只需要设置第一个参数,后面的四个参数均有默认值。
  3. 界面线程的创建
    -1)从CWinThread类派生自己的子类:假设为CUIThreadApp
    -2)重载CUIThreadApp的InitInstance(必须重载)与ExitInstance(可选重载)函数
    -3)在InitInstance函数中进行界面的创建
    -4)调用AfxBeginThread函数开始界面线程:AfBeginThread(RUNTIME_CLASS(CUIThreadApp))
2.2.2、工作者线程线程
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值