CreateThread给线程函数传递的参数
HANDLE WINAPI CreateThread
(
__in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes, // 指向SECURITY_ATTRIBUTES 的指针,为新线程指定安全描述
__in SIZE_T dwStackSize, // 初始化线程堆栈尺寸
__in LPTHREAD_START_ROUTINE lpStartAddress, //线程函数所指向的地址起始函数
__in_opt LPVOID lpParameter, // 给线程函数传递的参数
__in DWORD dwCreationFlags, // 有关线程的标志
__out_opt LPDWORD lpThreadId //系统分配给线程的ID );
----第一个参数是安全属性,一般设为null,使用缺省的安全属性。当我们想此线程有另外的子进程时,可改变它的属性。
----第二个参数是线程堆栈尺寸,一般设为0,表示与此应用的堆栈尺寸相同,即主线程与创建的线程一样长度的堆栈。并且其长度会根据需要自动变长。
----第三个参数,也是最重要的一个,是一个指向函数名的指针,或者函数名字
----第四个参数是你需要向线程函数传递的参数,一般是一个指向结构的指针。不需传递参数时,则这个参数设为null。
----第五个参数,传入与线程有关的一些标志,如果是CREATE_SUSPENDED,则创建一个挂起的线程,即这个线程本身已创建,它的堆栈也已创建。但这个线程不会被分配给CPU时间,只有当ResumeThread函数被调用后才能执行;当然,也可以调用SuspendThread函数再次挂起线程。要是标志为0,那么一旦建立线程,线程函数就被立即调用。一般传为0即可。 ----第六个参数是系统分配给这个线程的唯一的ID标志
// MultiTread2.cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h" #include <windows.h>
#include <stdio.h> #define MAX_THREADS 10 typedef struct MyData
{
int val1;
int val2;
//char key[32];
}MYDATA; DWORD WINAPI ThreadProc(LPVOID lpParam)
{
MYDATA *pmd = (MYDATA *)lpParam;
printf("%d\n", pmd->val1);
printf("%d\n", pmd->val2);
return ;
} DWORD(WINAPI *pThreadProc)(LPVOID lpParam); void fun()
{
pThreadProc = ThreadProc;
MYDATA mydt[MAX_THREADS]; HANDLE hThread[MAX_THREADS];
int i;
for (i = ; i < MAX_THREADS; i++)
{
mydt[i].val1 = i;
mydt[i].val2 = i + ;
hThread[i] = CreateThread(
NULL,// default security attributes
,// use default stack size
pThreadProc,// thread function
&mydt[i],// argument to thread function
, // use default creation flags
NULL);
if (hThread[i] == NULL)
{
ExitProcess(i);
}
}
// Wait until all threads have terminated.
WaitForMultipleObjects(MAX_THREADS, hThread, TRUE, INFINITE); //这样传给回调函数的参数不用定位static或者new出来的了
// Close all thread handles upon completion.
for (i = ; i < MAX_THREADS; i++)
{
CloseHandle(hThread[i]);
} } int _tmain(int argc, _TCHAR* argv[])
{
fun();
getchar();
return ;
}
注意:传给函数的参数,要保证当运行回调函数时候,参数不能被销毁。
比如这里参数是局部变量栈。
如果将
WaitForMultipleObjects(MAX_THREADS, hThread, TRUE, INFINITE); //这样传给回调函数的参数不用定位static或者new出来的了
屏蔽,
那么传递给回调函数的参数就可能已经被销毁,调用函数的时候就会出错、 除非将传入的参数定义为static 或者其他在调用完所有线程前不被销毁的变量
WaitForSingleObject的返回值能够指明调用线程为什么再次变为可调度状态。如果线程等待的对象变为已通知状态,那么返回值是 WAIT_OBJECT_0。如果设置的超时已经到期,则返回值是WAIT_TIMEOUT。如果将一个错误的值(如一个无效句柄)传递给 WaitForSingleObject,那么返回值将是WAIT_FAILED(若要了解详细信息,可调用GetLastError)。
DWORD WaitForMultipleObjects(
DWORD dwCount,
CONST HANDLE* phObjects,
BOOL fWaitAll,
DWORD dwMilliseconds
);
说明这一情况的一些示例代码:
HANDLE h[];
h[] = hProcess1;
h[] = hProcess2;
h[] = hProcess3;
DWORD dw = WaitForMultipleObjects(, h, FALSE, );
switch(dw)
{
case WAIT_FAILED:
// Bad call to function (invalid handle?)
break;
case WAIT_TIMEOUT:
// None of the objects became signaled within 5000 milliseconds.
break;
case WAIT_OBJECT_0 + :
// The process identified by h[0] (hProcess1) terminated.
break;
case WAIT_OBJECT_0 + :
// The process identified by h[1] (hProcess2) terminated.
break;
case WAIT_OBJECT_0 + :
// The process identified by h[2] (hProcess3) terminated.
break;
}
如果为fWaitAll参数传递 FALSE,WaitForMultipleObjects就从索引0开始向上对句柄数组进行扫描,同时已通知的第一个对象终止等待状态。
这可能产生一些 你不希望有的结果。
例如,通过将3个进程句柄传递给该函数,你的线程就会等待3个子进程终止运行。如果数组中索引为0的进程终止运 行,WaitForMultipleObjects就会返回。这时该线程就可以做它需要的任何事情,然后循环反复,等待另一个进程终止运行。
如果该线程传 递相同的3个句柄,该函数立即再次返回WAIT_OBJECT_0。除非删除已经收到通知的句柄,否则代码就无法正确地运行
CreateThread给线程函数传递的参数的更多相关文章
- 【VS开发】CreateThread给线程函数传递的参数
CreateThread给线程函数传递的参数 HANDLE WINAPI CreateThread ( __in_opt LPSECURITY_ATTRIBUTES lpThreadAttribu ...
- C++ 并发编程2 --向线程函数传递参数
1向线程函数传递参数比较简单,一般的形式如下 void f(int i,std::string const& s);std::thread t(f,3, "hello"); ...
- Python学习之路:函数传递可变参数与不可变参数
函数传参的方法: 太基础了,8说了 直接上重点 一.可变参数的传递 可变参数有:列表.集合.字典 直接上代码: a = [1, 2] def fun(a): print('传入函数时a的值为:', a ...
- JS函数传递字符串参数(符号转义)
原文链接:https://blog.csdn.net/Myname_China/article/details/82907965 JS函数传递字符串参数,如果没有转义处理,在接收的时候无法正确的接收字 ...
- c++线程创建传递的参数发生改变
看看如下代码,觉得输出会是什么? #include "stdafx.h" #include <windows.h> #include <iostream> ...
- python 函数传递可变参数的用法
可变参数 在Python函数中,还可以定义可变参数.顾名思义,可变参数就是传入的参数个数是可变的,可以是1个.2个到任意个,还可以是0个. 我们以数学题为例子,给定一组数字a,b,c……,请计算a2 ...
- [置顶] 函数传递不定参数理解-c语言
感性认识 Typedef char *va_list;/*这个在<stdatg.h>中有定义*/ #define va_start(ap,p) (ap=(char*)(&(p)+1 ...
- C++和Java函数传递数组参数比较
如果我想实现函数参数传递数组的业务需求,在Java中很容易实现,如下所示.因为Java有.length方法,可以获取数组的长度. public class Test { public static v ...
- CreateThread创建线程 互斥量锁
HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes,//SD:线程安全相关的属性,常置为NULL SIZE_T dwStackS ...
随机推荐
- Maven Web Project设置Webcontent路径
1,新建maven-archetype-webapp 2,右键项目-->Properties-->选中Project Facets中的Runtimes标签,然后Java版本改为1.8,Dy ...
- 生成id
package com.develop.web.util; import java.security.MessageDigest; import java.text.SimpleDateFormat; ...
- Python 协程并发爬虫网页
简单爬虫实例: 功能:通过urllib.request实现网站爬虫,捕获网站内容. from urllib import request def f(url): print("GET:%s& ...
- ORA-00600: internal error code, arguments: [kcblin_3], [103], [253952], [8192], [32769], [312], [640], [], [], [], [], []解决方法
昨晚,一SQL执行的时候报了ORA-00600: internal error code, arguments: [kcblin_3], [103], [253952], [8192], [32769 ...
- Bitmap的秘密
作者: 周海鹏 来源: infoQ 发布时间: 2015-02-13 11:26 阅读: 4999 次 推荐: 10 原文链接 [收藏] 之前已经参加过几次QCon峰会,不过今年QCo ...
- python 的运行方式和基础变量
机器语言:直接用计算机能听的懂得二进制去编写程序,需要了解硬件细节 优点:执行效率高 缺点:开发效率低汇编语言:用英文单词取代二进制指令去编写程序 优点:开发效率高于机器语言 缺点:执行效率低于机器语 ...
- iOS UIAlertController在iPhone与iPad上的区别
很简单的一段代码: // 首先声明一个UIAlertController对象 private var alertController: UIAlertController! // 初始化UIAlert ...
- 剑指offer(38)二叉树的深度
题目描述 输入一棵二叉树,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度. 题目分析 树的深度=左子树的深度和右子树深度中最大者+1 代码 fu ...
- Hi3519v101 SDK安装及升级
安装SDK 1.解压tgz压缩包 将 Hi3519V101_SDK_Vx.x.x.x.tgz 压缩包放入共享文件夹中,并解压到Linux内部如 /sdk 目录下,因为在共享目录中编译容易出现各种错误. ...
- MySQL 变量类型
用户定义的变量(前缀为@): 您可以访问任何用户定义的变量,而无需声明或初始化它.如果引用尚未初始化的变量,则其值为NULL和字符串类型. select @now2; NULL set赋值: set ...