您的位置:首页 > 其它

多线程第一篇:使用_beginthreadex创建线程

2013-12-15 08:57 591 查看
我们先来了解一下线程的相关函数:

CreateThread函数:

HANDLE WINAPI CreateThread (
_In_opt_    LPSECURITY_ATTRIBUTES   lpThreadAttributes ,  // pointer to security attributes
_In_          SIZE_T                               dwStackSize,           // initial thread stack size
_In_          LPTHREAD_START_ROUTINE    lpStartAddress,    // pointer to thread function
_In_opt_    LPVOID                                   lpParameter,       // argument for new thread
_In_          DWORD                                  dwCreationFlags,      // creation flags
_Out_opt_  LPDWORD                              lpThreadId                // pointer to receive thread ID
);
第一个参数是指向SECURITY_ATTRIBUTES型态的结构的指针。在Windows 98中忽略该参数。在Windows NT中,它被设为NULL。

第二个参数是用于新线程的初始堆栈大小,默认值为0。在任何情况下,Windows根据需要动态延长堆栈的大小。

第三个参数是指向线程函数的指标。函数名称没有限制,但是必须以下列形式声明:

DWORD WINAPI ThreadProc (PVOID pParam) ;

第四个参数为传递给ThreadProc的参数。这样主线程和从属线程就可以共享数据。

第五个参数通常为0,但当建立的线程不马上执行时为旗标CREATE_SUSPENDED。线程将暂停直到呼叫ResumeThread来恢复线程的执行为止。

第六个参数是一个指标,指向接受执行绪ID值的变量。

WaitForSingleObject:等待一个object触发,参数为object的句柄

DWORD WINAPI WaitForSingleObject(
_In_  HANDLE hHandle,
_In_  DWORD dwMilliseconds
);
第一个参数为要等待的内核对象。

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

函数返回值:

WAIT_OBJECT_0:在指定的时间内对象被触发,函数返回WAIT_OBJECT_0。

WAIT_TIMEOUT:超过最长等待时间对象仍未被触发返回WAIT_TIMEOUT。

WAIT_FAILED:传入参数有错误将返回WAIT_FAILED

_beginthreadex()和CreateThread参数是一样的,一般来讲在创建线程的时候尽量要用_beginthreadex(),我们来看看原因:

由于标准c程序库中有许多全局变量,当一个线程改变全局变量的时候会影响到其他线程,或者整个进程,例如c语言中的errno.

为了解决这个问题,Windows操作系统提供了这样的一种解决方案——每个线程都将拥有自己专用的一块内存区域来供标准C运行库中所有有需要的函数使用。而且这块内存区域的创建就是由C/C++运行库函数_beginthreadex()来负责的。

_beginthreadex()函数在创建新线程时会分配并初始化一个_tiddata块。这个_tiddata块自然是用来存放一些需要线程独享的数据。事实上新线程运行时会首先将_tiddata块与自己进一步关联起来。然后新线程调用标准C运行库函数如strtok()时就会先取得_tiddata块的地址再将需要保护的数据存入_tiddata块中。这样每个线程就只会访问和修改自己的数据而不会去篡改其它线程的数据了。因此,如果在代码中有使用标准C运行库中的函数时,尽量使用_beginthreadex()来代替CreateThread().

(-----来自http://blog.csdn.net/morewindows/article/details/7421759)

注意:

(1)C++主线程终止时,同时也会终止所有主线程创建的子线程,不管子线程有没有执行完毕。

(2)如果某线程挂起,然后有调用WaitForSingleObject等待该线程,就会导致死锁。

( 3 ) 线程执行时候,事件处于未触发,执行完毕后自动设为触发状态.

#include <iostream>
#include <windows.h>
#include <process.h>

unsigned int __stdcall ThreadFun(LPVOID )
{
std::cout<< "子线程ID:" <<GetCurrentThreadId()<< std::endl ;
return 0;
}

int main ()
{
const int thread_num = 10;
HANDLE handle[thread_num ];
for ( int i = 0 ; i<10; ++i ){
handle[i ] = (HANDLE) _beginthreadex(NULL ,0,ThreadFun, NULL,0,NULL );
}

//HANDLE handle = CreateThread(NULL,0,ThreadFun,NULL,0,NULL);

//WaitForSingleObject(handle,INFINITE);
WaitForMultipleObjects( thread_num,handle ,true,INFINITE); //为了防止子线程没有执行就结束了.
return 0;
}




[align=left] [/align]



从这幅图中可以看出线程之间的竞争,造成线程中的输出被打断.

参考了网上好多博客例子,只有一小部分是自己总结的.
大多数来自博客:http://blog.csdn.net/morewindows/article/details/7421759
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: