一.多线程概述
多线程(multithreading)是一种并发编程的方式,它允许程序同时执行多个任务。
1.功能
并发执行:多线程技术使得一个程序能够同时运行多个任务,这些任务在逻辑上相互独立,但在执行过程中可能共享某些资源。
资源共享:在多线程程序中,多个线程可以访问共享的内存空间,这些共享资源包括变量、数据结构等。
同步与互斥:为了保证多线程程序的正确性和效率,需要实现线程之间的同步和互斥,以避免数据竞争和死锁等问题。
2.作用
(1)提高程序性能:
充分利用CPU资源:多线程可以充分利用多核处理器的优势,通过并行执行多个线程来提高程序的执行效率。当线程数不大于CPU数目时,不同的线程可以运行在不同的CPU上,从而实现真正的并行运算。
减少等待时间:在需要等待的任务(如I/O操作、网络请求等)上,多线程可以使得程序在等待期间继续执行其他任务,从而减少整体等待时间。
优化用户体验:在图形用户界面(GUI)应用程序中,多线程可以用于执行与用户交互无关的后台任务,如图片加载、数据处理等,从而提高用户界面的响应性和流畅度。
(2)实现并发处理:
处理多个请求:在服务器应用程序中,多线程可以提高系统的响应性,允许同时处理多个客户端请求。这对于需要处理大量并发连接的应用程序至关重要。
任务拆分与并行处理:对于复杂或耗时的任务,可以通过多线程将其拆分为多个子任务并行处理,以加快整体处理速度。
(3)简化程序设计:
在某些场景下,使用多线程可以更自然地表达问题,避免复杂的同步和异步编程模型。例如,在图形处理、网络通信等领域中,多线程可以使得程序设计更加直观和简洁。
(4)提高资源利用率:
通过并行执行多个任务,多线程可以更有效地利用系统资源(如CPU、内存等),提高整体效率。这有助于减少资源闲置和浪费。
二.代码实现
以Windows平台上多线程编程做示例。
1.包含头文件
#include <windows.h>
2.定义线程函数
线程函数是线程执行的入口点。它必须遵循特定的签名,即返回DWORD,并接受一个指向void的指针(typedef void far *LPVOID)作为参数。
DWORD WINAPI ThreadFunction(LPVOID lpParam) {
// 将参数转换为适当的类型
int* param = static_cast<int*>(lpParam);
// 执行线程的工作
for (int i = 0; i < *param; ++i) {
std::cout << "Thread is running: " << i << std::endl;
Sleep(1000); // 休眠1秒,以便观察输出
}
// 线程函数返回0通常表示成功
return 0;
}
3.main函数中创建并管理线程
在main函数中,你将调用CreateThread来创建线程,并使用WaitForSingleObject等待线程结束,最后使用CloseHandle关闭线程句柄。
int main() {
HANDLE hThread;
DWORD dwThreadId;
int param = 5; // 传递给线程的参数
// 创建线程
hThread = CreateThread(
NULL, // 默认安全属性
0, // 默认堆栈大小
ThreadFunction, // 线程函数
¶m, // 传递给线程函数的参数(注意:这里传递的是地址)
0, // 默认创建标志
&dwThreadId); // 接收新线程的标识符
if (hThread == NULL) {
// 处理错误,例如线程创建失败
std::cerr << "Failed to create thread" << std::endl;
return 1;
}
// 等待线程结束
WaitForSingleObject(hThread, INFINITE); //阻塞
// 关闭线程句柄
CloseHandle(hThread);
// 主线程可以继续执行其他任务或结束
std::cout << "Main thread ends." << std::endl;
return 0;
}
三.注意
1.线程间共享数据时需要同步,以避免数据竞争。在这个简单的例子中,我们没有共享数据,但在更复杂的多线程程序中,可能需要使用互斥锁(CRITICAL_SECTION、std::mutex等)或其他同步机制。
2.线程创建后,CreateThread返回的句柄应使用CloseHandle进行关闭,以释放系统资源。然而,如果线程仍在运行,则关闭句柄并不会影响线程的执行。线程将在其执行完毕后自动终止。