使用线程——创建线程

CreateThread函数创建一个进程的新的线程。创建线程必须指定新线程要执行的代码的起始地址。通常,起始地址是程序代码中定义的函数的名称(有关更多信息,请参阅ThreadProc)。此函数采用单个参数并返回DWORD值。一个进程可以让多个线程同时执行相同的功能。

以下是演示如何创建执行本地定义函数的新线程的简单示例MyThreadFunction

调用线程使用WaitForMultipleObjects函数持久化,直到所有工作线程终止。调用线程在等待时阻塞; 为了继续处理,调用线程将使用WaitForSingleObject并等待每个工作线程发信号通知其等待对象。请注意,如果要在终止之前关闭工作线程的句柄,则不会终止工作线程。但是,句柄将不可用于后续函数调用。

#include <windows.h>
#include <tchar.h>
#include <strsafe.h>#define MAX_THREADS 3
#define BUF_SIZE 255DWORD WINAPI MyThreadFunction( LPVOID lpParam );
void ErrorHandler(LPTSTR lpszFunction);// Sample custom data structure for threads to use.
// This is passed by void pointer so it can be any data type
// that can be passed using a single void pointer (LPVOID).
typedef struct MyData {int val1;int val2;
} MYDATA, *PMYDATA;int _tmain()
{PMYDATA pDataArray[MAX_THREADS];DWORD   dwThreadIdArray[MAX_THREADS];HANDLE  hThreadArray[MAX_THREADS]; // Create MAX_THREADS worker threads.for( int i=0; i<MAX_THREADS; i++ ){// Allocate memory for thread data.pDataArray[i] = (PMYDATA) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,sizeof(MYDATA));if( pDataArray[i] == NULL ){// If the array allocation fails, the system is out of memory// so there is no point in trying to print an error message.// Just terminate execution.ExitProcess(2);}// Generate unique data for each thread to work with.pDataArray[i]->val1 = i;pDataArray[i]->val2 = i+100;// Create the thread to begin execution on its own.hThreadArray[i] = CreateThread( NULL,                   // default security attributes0,                      // use default stack size  MyThreadFunction,       // thread function namepDataArray[i],          // argument to thread function 0,                      // use default creation flags &dwThreadIdArray[i]);   // returns the thread identifier // Check the return value for success.// If CreateThread fails, terminate execution. // This will automatically clean up threads and memory. if (hThreadArray[i] == NULL) {ErrorHandler(TEXT("CreateThread"));ExitProcess(3);}} // End of main thread creation loop.// Wait until all threads have terminated.WaitForMultipleObjects(MAX_THREADS, hThreadArray, TRUE, INFINITE);// Close all thread handles and free memory allocations.for(int i=0; i<MAX_THREADS; i++){CloseHandle(hThreadArray[i]);if(pDataArray[i] != NULL){HeapFree(GetProcessHeap(), 0, pDataArray[i]);pDataArray[i] = NULL;    // Ensure address is not reused.}}return 0;
}DWORD WINAPI MyThreadFunction( LPVOID lpParam ) 
{ HANDLE hStdout;PMYDATA pDataArray;TCHAR msgBuf[BUF_SIZE];size_t cchStringSize;DWORD dwChars;// Make sure there is a console to receive output results. hStdout = GetStdHandle(STD_OUTPUT_HANDLE);if( hStdout == INVALID_HANDLE_VALUE )return 1;// Cast the parameter to the correct data type.// The pointer is known to be valid because // it was checked for NULL before the thread was created.pDataArray = (PMYDATA)lpParam;// Print the parameter values using thread-safe functions.StringCchPrintf(msgBuf, BUF_SIZE, TEXT("Parameters = %d, %d\n"), pDataArray->val1, pDataArray->val2); StringCchLength(msgBuf, BUF_SIZE, &cchStringSize);WriteConsole(hStdout, msgBuf, (DWORD)cchStringSize, &dwChars, NULL);return 0; 
} void ErrorHandler(LPTSTR lpszFunction) 
{ // Retrieve the system error message for the last-error code.LPVOID lpMsgBuf;LPVOID lpDisplayBuf;DWORD dw = GetLastError(); FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_IGNORE_INSERTS,NULL,dw,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPTSTR) &lpMsgBuf,0, NULL );// Display the error message.lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, (lstrlen((LPCTSTR) lpMsgBuf) + lstrlen((LPCTSTR) lpszFunction) + 40) * sizeof(TCHAR)); StringCchPrintf((LPTSTR)lpDisplayBuf, LocalSize(lpDisplayBuf) / sizeof(TCHAR),TEXT("%s failed with error %d: %s"), lpszFunction, dw, lpMsgBuf); MessageBox(NULL, (LPCTSTR) lpDisplayBuf, TEXT("Error"), MB_OK); // Free error-handling buffer allocations.LocalFree(lpMsgBuf);LocalFree(lpDisplayBuf);
}

MyThreadFunction函数避免使用C运行时库(CRT),因为它的许多函数都不是线程安全的,特别是如果您不使用多线程CRT。如果要在ThreadProc函数中使用CRT ,请改用_beginthreadex函数。

如果创建线程在新线程之前退出,则传递局部变量的地址是有风险的,因为指针变为无效。相反,要么将指针传递给动态分配的内存,要么让创建线程等待新线程终止。数据也可以使用全局变量从创建线程传递到新线程。对于全局变量,通常需要通过多个线程同步访问。有关同步的详细信息,请参阅同步多个线程的执行。

创建线程可以使用CreateThread的参数来指定以下内容:

新线程句柄的安全属性。这些安全属性包括一个继承标志,用于确定子进程是否可以继承句柄。安全性属性还包括安全描述符,系统使用该描述符在授予访问权限之前对线程句柄的所有后续使用执行访问检查。
新线程的初始堆栈大小。线程的堆栈自动分配在进程的内存空间中; 系统根据需要增加堆栈,并在线程终止时释放它。有关更多信息,请参阅线程堆栈大小。
一个创建标志,使您可以创建处于挂起状态的线程。挂起时,线程不会运行,直到调用ResumeThread函数。
您还可以通过调用CreateRemoteThread函数来创建线程。调试器进程使用此函数来创建在正在调试的进程的地址空间中运行的线程。

相关话题

终止线程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/448214.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

location

location (地址)&#xff1a; 是浏览器 window 上的一个对象&#xff0c;不仅能处理当前页面的网络地址&#xff0c;还可以实现页面间的跳转 页面的跳转&#xff1a; 为什么使用它&#xff1f; 使我们也可以通过脚本语言&#xff0c;也能实现 a 链接&#xff0c;同样的效果&…

linux :Docker 方式 安装 zookeeper、阿里服务器上 Docker 运行 zookeeper

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1. 查找官方镜像&#xff0c;并下载镜像&#xff1a; # 搜索镜像&#xff1a; docker search zookeeper# 拉取镜像&#xff1a;docker …

使用线程池功能

此示例创建自定义线程池&#xff0c;创建工作项和线程池计时器&#xff0c;并将它们与清理组关联。该池由一个持久性线程组成。它演示了以下线程池函数的使用&#xff1a; CloseThreadpool CloseThreadpoolCleanupGroupCloseThreadpoolCleanupGroupMembersCloseThreadpoolWait…

制动刹车片六个养护要点

刹车片属于消耗品&#xff0c;在使用中会逐渐磨损&#xff0c;当磨损到极限位置时&#xff0c;必须更换&#xff0c;否则将降低制动的效果&#xff0c;甚至造成安全事故。 制动刹车片关乎生命安全&#xff0c;必须谨慎对待。 大多数轿车采用前盘后鼓式制动器结构&#xff0c;一…

Learn day4 函数参数\变量\闭包\递归

1.函数描述 # ### 函数 """ (1)函数的定义:功能 (包裹一部分代码 实现某一个功能 达成某一个目的) (2)函数特点:可以反复调用,提高代码的复用性,提高开发效率,便于维护管理 """# (3) 函数的基本格式 """ # 函数的定义处 def fun…

Java 中去除字符串中空格的方法

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1、方法分类 str.trim(); //去掉首尾空格str.replace(" ",""); //去除所有空格&#xff0c;包括首尾、中间str.re…

使用重定向的输入和输出创建子进程

本主题中的示例演示如何使用控制台进程中的CreateProcess函数创建子进程。它还演示了一种使用匿名管道重定向子进程的标准输入和输出句柄的技术。请注意&#xff0c;命名管道也可用于重定向进程I / O. 所述CreatePipe函数使用SECURITY_ATTRIBUTES结构来创建可继承句柄读写两个…

手动挡停车时挂档有技巧

徐小姐来电&#xff1a;我家的汽车要年检了&#xff0c;前几天&#xff0c;工作人员帮我把车子开进检测站去检测&#xff0c;开回来后停在原位上&#xff0c;然后把钥匙交给我。我拿钥匙一点火&#xff0c;车子就突然往前动了&#xff0c;根本没有时间反应&#xff0c;已经撞到…

LOJ 3156: 「NOI2019」回家路线

题目传送门&#xff1a;LOJ #3156。 题意简述&#xff1a; 有一张 \(n\) 个点 \(m\) 条边的有向图&#xff0c;边有两个权值 \(p_i\) 和 \(q_i\)&#xff08;\(p_i<q_i\)&#xff09;表示若 \(p_i\) 时刻在这条边的起点&#xff0c;则 \(q_i\) 时刻能到达这条边的终点。 你需…

线程池概述

线程池 一个线程池的工作线程代表应用程序的高效执行异步回调的集合。线程池主要用于减少应用程序线程的数量并提供工作线程的管理。应用程序可以对工作项进行排队&#xff0c;将工作与可等待的句柄相关联&#xff0c;根据计时器自动排队&#xff0c;并与I / O绑定。 线程池架…

WEB 请求处理二:Nginx 请求 反向代理

上一篇《WEB请求处理一&#xff1a;浏览器请求发起处理》&#xff0c;我们讲述了浏览器端请求发起过程&#xff0c;通过DNS域名解析服务器IP&#xff0c;并建立TCP连接&#xff0c;发送HTTP请求。本文将讲述请求到达反向代理服务器的一个处理过程&#xff0c;比如&#xff1a;在…

方向盘的正确驾驭方法

如果问您油门踏板和方向盘哪个与驾驶员最“亲密”&#xff0c;您会选择谁呢&#xff1f;恐怕还是方向盘吧。如果汽车行驶过程中您的双手同时离开了方向盘&#xff0c;那么事故的隐患也就随之而来。下面我们就为您全面介绍汽车方向盘的正确使用方法。专家介绍&#xff0c;握方向…

SQL server 2005中无法新建作业(Job)的问题

客户端是使用企业管理其&#xff08;Management Studio&#xff09;新建job&#xff0c;总是无法创建&#xff0c;查找了很多资料&#xff0c;有的说是需要sp2, 但有的又说不是... ... 没有时间去研究为什么&#xff0c;但确有一种方法解决&#xff1a;到服务器端去创建job&…

线程池API

线程池API 线程池应用程序编程接口&#xff08;API&#xff09;使用基于对象的设计。以下每个对象都由用户模式数据结构表示&#xff1a; 池对象是一组可用于执行工作的工作线程。每个进程可以根据需要创建具有不同特征的多个隔离池。每个进程都有一个默认池。清理组与一组回…

WEB 请求处理 一:浏览器 请求发起处理

最近&#xff0c;终于要把《WEB请求处理系列》提上日程了&#xff0c;一直答应小伙伴们给分享一套完整的WEB请求处理流程&#xff1a;从浏览器、Nginx、Servlet容器&#xff0c;最终到应用程序WEB请求的一个处理流程&#xff0c;前段时间由于其他工作事情的安排&#xff0c;一直…

离合器半联动探秘

离合器踏板作用是切断发动机和变速箱之间的动力&#xff0c;有利于起步、变速、和停车。那么如何更好的使用它呢&#xff1f; 离合器的五种状态示意图 离合器半联动的使用方法揭密如下&#xff1a; 离合器半联动的使用探密之一 将离合器抬到车开始动时你就别再抬了&#xff0c;…

Biztalk Server 2006安装配置

前段时间收到了来自beta.microsoft.com的BTS20006 Beta2的下载地址&#xff0c;这两天对它进行了一番安装配置。下面把一些经过和步骤和大家分享一下&#xff0c;手中有一些去年的Biztalk Server2004版本的培训资料&#xff0c;里面有11个Lab。需要的朋友请留下mail&#xff0c…

apache 官方 Dubbo 文档

只是分享、记录一下 dubbo 的文档地址&#xff1a;apache 官方 Dubbo 文档 其页面内容如下&#xff1a;&#xff08;我是用 chrome 直接右键翻译的&#xff0c;原文档是英文的&#xff09;

制动踏板是什么?

制动踏板就是脚刹&#xff08;行车制动器&#xff09;的踏板&#xff0c;使运行中的机车、车辆及其他运输工具或机械等停止或减低速度的动作。制动的一般原理是在机器的高速轴上固定一个轮或盘&#xff0c;在机座上安装与之相适应的闸瓦、带或盘&#xff0c;在外力作用下使之产…

CSS Framework 960 Grid System (收)

CSS框架 &#xff1a;960 Grid System 官网&#xff1a;http://960.gs/ 什么是框架&#xff1f;框架是一种你能够使用在你的web项目中概念上的结构。CSS框架一般是CSS文件的集合&#xff0c;包括基本风格的字体排版&#xff0c;表单样式&#xff0c;表格布局等等&#xff0c;比…