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标志 windows

 

// 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 0;
}

DWORD(WINAPI *pThreadProc)(LPVOID lpParam);

void fun()
{
    pThreadProc = ThreadProc;
    MYDATA mydt[MAX_THREADS];

    HANDLE hThread[MAX_THREADS];
    int i;
    for (i = 0; i < MAX_THREADS; i++)
    {
        mydt[i].val1 = i;
        mydt[i].val2 = i + 1;
        hThread[i] = CreateThread(
            NULL,// default security attributes
            0,// use default stack size
            pThreadProc,// thread function
            &mydt[i],// argument to thread function
            0, // 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 = 0; i < MAX_THREADS; i++)
    {
        CloseHandle(hThread[i]);
    }

}

int _tmain(int argc, _TCHAR* argv[])
{
    fun();
    getchar();
    return 0;
}

 

注意:传给函数的参数,要保证当运行回调函数时候,参数不能被销毁。数组

好比这里参数是局部变量栈。安全

若是将 ide

 WaitForMultipleObjects(MAX_THREADS, hThread, TRUE, INFINITE); //这样传给回调函数的参数不用定位static或者new出来的了
屏蔽,
那么传递给回调函数的参数就可能已经被销毁,调用函数的时候就会出错、


除非将传入的参数定义为static 或者其余在调用完全部线程前不被销毁的变量

WaitForMultipleObjects
WaitForSingleObject的返回值可以指明调用线程为何再次变为可调度状态。若是线程等待的对象变为已通知状态,那么返回值是 WAIT_OBJECT_0。若是设置的超时已经到期,则返回值是WAIT_TIMEOUT。若是将一个错误的值(如一个无效句柄)传递给 WaitForSingleObject,那么返回值将是WAIT_FAILED(若要了解详细信息,可调用GetLastError)。
下面这个函数WaitForMultipleObjects与WaitForSingleObject函数很类似,区别在于它容许调用线程同时查看若干个内核对象的已通知状态:
DWORD WaitForMultipleObjects(
    DWORD dwCount,
   CONST HANDLE* phObjects,
   BOOL fWaitAll,
   DWORD dwMilliseconds
);

 

dwCount参数用于指明想要让函数查看的内核对象的数量。这个值必须在1与MAXIMUM_WAIT_OBJECTS(在Windows头文件中定义为64)之间。
 
phObjects参数是指向内核对象句柄的 数组的指针。
能够以两种不一样的方式来使用WaitForMultipleObjects函数。
一种方式是让线程进入等待状态,直到指定内核对象中的任何一个变为已通知状态。
另外一种方式是让线程进入等待状态,直到全部指定的内核对象都变为已通知状态。
fWaitAll参数告诉该函数,你想要让它使用何种方式。
若是为该参数传递TRUE,那么在全部对象变为已通知状态以前,该函数将不容许调用线程运行。
dwMilliseconds参数的做用与它在WaitForSingleObject中的做用彻底相同。若是在等待的时候规定的时间到了,那么该函数不管如何都会返回。
一样,一般为该参数传递INFINITE,可是在编写代码时应该当心,以免出现死锁状况。
 
WaitForMultipleObjects函数的返回值告诉调用线程,为 什么它会被从新调度。可能的返回值是WAIT_FAILED和WAIT_TIMEOUT,这两个值的做用是很清楚的。
若是fWaitAll参数传递 TRUE,同时全部对象均变为已通知状态,那么返回值是WAIT_OBJECT_0。
若是为fWaitAll传递FALSE,那么一旦任何一个对象变为已 通知状态,该函数便返回。
在这种状况下,你可能想要知道哪一个对象变为已通知状态。返回值是WAIT_OBJECT_0 与(WAIT_OBJECT_0 + dwCount-1)之间的一个值。
换句话说,若是返回值不是WAIT_TIMEOUT,也不是WAIT_FAILED,那么应该从返回值中减去 WAIT_OBJECT_0。产生的数字是做为第二个参数传递给WaitForMultipleObjects的句柄数组中的索引。
该索引说明哪一个对象变 为已通知状态。
 
说明这一状况的一些示例代码:
HANDLE h[3];
h[0] = hProcess1;
h[1] = hProcess2;
h[2] = hProcess3;
DWORD dw = WaitForMultipleObjects(3, h, FALSE, 5000);
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 + 0:
      // The process identified by h[0] (hProcess1) terminated.
      break;
   case WAIT_OBJECT_0 + 1:
      // The process identified by h[1] (hProcess2) terminated.
      break;
   case WAIT_OBJECT_0 + 2:
      // The process identified by h[2] (hProcess3) terminated.
      break;
}
 

若是为fWaitAll参数传递 FALSE,WaitForMultipleObjects就从索引0开始向上对句柄数组进行扫描,同时已通知的第一个对象终止等待状态。函数

这可能产生一些 你不但愿有的结果。spa

例如,经过将3个进程句柄传递给该函数,你的线程就会等待3个子进程终止运行。若是数组中索引为0的进程终止运 行,WaitForMultipleObjects就会返回。这时该线程就能够作它须要的任何事情,而后循环反复,等待另外一个进程终止运行。线程

若是该线程传 递相同的3个句柄,该函数当即再次返回WAIT_OBJECT_0。除非删除已经收到通知的句柄,不然代码就没法正确地运行指针

相关文章
相关标签/搜索