多线程笔记

来源:互联网 发布:webpack 压缩混淆js 编辑:程序博客网 时间:2024/04/20 03:47

// 多线程示例程序

#include <windows.h>#include <stdio.h>#include <process.h>int tally = 0;//glableunsigned int __stdcall ThreadProc(PVOID pm){for(int i = 1; i <= 50; i++){tally += 1;}printf("tally=%d\n", tally);_endthreadex(0); // 有这条语句的线程函数不能当普通函数使用。因为它会结束当前线程。return 0;}DWORD WINAPI ThreadFun(LPVOID pM){enum{MAXHANDLE = 1};HANDLE handle[MAXHANDLE];handle[0] = (HANDLE)_beginthreadex(NULL, 0, ThreadProc, NULL, 0, NULL);WaitForMultipleObjects(MAXHANDLE, handle, TRUE, INFINITE);        CloseHandle(handle[0]);static int nIndex = 0;printf("第%d个子线程ID号是%d\n", ++nIndex, GetCurrentThreadId());return 0;}
#include <stdio.h>#include <stdlib.h>#include "main.h"#include <process.h>  #include <windows.h>#include"threadProc.h"int main(){HANDLE handle1 = CreateThread(NULL, 0, ThreadFun, NULL, 0, NULL); HANDLE handle2 = CreateThread(NULL, 0, ThreadFun, NULL, 0, NULL); WaitForSingleObject(handle1, INFINITE);WaitForSingleObject(handle2, INFINITE);CloseHandle(handle1);CloseHandle(handle2);getchar();return 0;}

注意:线程函数中如果有_beginthreadex(0)则不能当普通函数使用,因为_beginthreadex(0)会结束当前线程。

// 函数原型:unsigned long _beginthreadex(    void *security,    unsigned stack_size,    unsigned ( __stdcall *start_address )( void * ),    void *arglist, /* 传给线程函数的参数的指针 */    unsigned initflag,    unsigned *thrdaddr );

以下内容来源于互联网:

1、CreateThread 和 _beginthreadex 区别:

CreateThread是系统API,_beginthreadex是CRT(C Run Time Library 运行时库)函数。

_beginthreadex内部会调用CreateThread函数。

_endthreadex会释放_beginthreadextiddata结构分配的内存。
如果在除主线程之外的任何线程中进行一下操作,你就应该使用多线程版本的C runtime library,并使用_beginthreadex_endthreadex
              (1) 使用malloc()和free(),或是newdelete
              (2) 使用stdio.h或io.h里面声明的任何函数
              (3) 使用浮点变量或浮点运算函数
              (4) 调用任何一个使用了静态缓冲区的runtime函数,比如:asctime(),strtok()或rand()

2、_beginthreadex_beginthread区别
_beginthreadex内部会自动调用 _endthreadex
_beginthread内部会自动调用_endthread
_endthread内部会自动调用CloseHandle关闭当前Thread内核对象的句柄,所以在用_beginthread 时我们不需要在主线程中调用CloseHandle来关闭子线程的句柄。 

_endthreadex相比_endthread而言更安全。它不会自动关闭当前Thread内核对象的句柄。所以在用_beginthreadex时我们需要用CloseHandle来关闭子线程的句柄。


以下内容来源于http://blog.csdn.net/morewindows/article/details/7421759

第一个 CreateThread

函数功能:创建线程

函数原型:

HANDLEWINAPICreateThread(

  LPSECURITY_ATTRIBUTESlpThreadAttributes,

  SIZE_TdwStackSize,

  LPTHREAD_START_ROUTINElpStartAddress,

  LPVOIDlpParameter,

  DWORDdwCreationFlags,

  LPDWORDlpThreadId

);

函数说明:

第一个参数表示线程内核对象的安全属性,一般传入NULL表示使用默认设置。

第二个参数表示线程栈空间大小。传入0表示使用默认大小(1MB)。

第三个参数表示新线程所执行的线程函数地址,多个线程可以使用同一个函数地址。

第四个参数是传给线程函数的参数。

第五个参数指定额外的标志来控制线程的创建,为0表示线程创建之后立即就可以进行调度,如果为CREATE_SUSPENDED则表示线程创建后暂停运行,这样它就无法调度,直到调用ResumeThread()

第六个参数将返回线程的ID号,传入NULL表示不需要返回该线程ID号。

函数返回值:

成功返回新线程的句柄,失败返回NULL 

 

第二个 WaitForSingleObject

函数功能:等待函数 – 使线程进入等待状态,直到指定的内核对象被触发。

函数原形:

DWORDWINAPIWaitForSingleObject(

  HANDLEhHandle,

  DWORDdwMilliseconds

);

函数说明:

第一个参数为要等待的内核对象。

第二个参数为最长等待的时间,以毫秒为单位,如传入5000就表示5秒,传入0就立即返回,传入INFINITE表示无限等待。

因为线程的句柄在线程运行时是未触发的,线程结束运行,句柄处于触发状态。所以可以用WaitForSingleObject()来等待一个线程结束运行。

函数返回值:

在指定的时间内对象被触发,函数返回WAIT_OBJECT_0。超过最长等待时间对象仍未被触发返回WAIT_TIMEOUT。传入参数有错误将返回WAIT_FAILED

原创粉丝点击