标签:
先介绍一个创建线程的API,参考:https://msdn.microsoft.com/en-us/library/windows/desktop/ms682453%28v=vs.85%29.aspx
Creates a thread to execute within the virtual address space of the calling process.
HANDLE WINAPI CreateThread(
_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
_In_ SIZE_T dwStackSize,
_In_ LPTHREAD_START_ROUTINE lpStartAddress,
_In_opt_ LPVOID lpParameter,
_In_ DWORD dwCreationFlags,
_Out_opt_ LPDWORD lpThreadId
);
使用范例参考MSDN:https://msdn.microsoft.com/en-us/library/windows/desktop/ms682516%28v=vs.85%29.aspx
举例说明线程:
#include <iostream> #include <windows.h> using namespace std; #define MAX_THREADS 20 #define BUF_SIZE 255 DWORD dwAccessOrder = 0; DWORD WINAPI MyThreadFunction(LPVOID lpPara) { DWORD *dwPara = (DWORD*)lpPara; cout << "这是第" << *dwPara << "个启动的线程!" << endl; return 0; } int main() { DWORD dwThreadIdArray[MAX_THREADS]; HANDLE hThreadArray[MAX_THREADS]; LPVOID lpParam = nullptr; for (int i = 0; i < MAX_THREADS; i++) { lpParam = &i; //可能有如下情况发生:参数还没有传递给线程,就已经把线程起起来了,比如i=12时,起起来了一个线程 //线程还未接收到参数12时,就进入了下一次循环,i被覆盖,被赋值为了13,于是这时候又 //起起来一个线程,可能就和刚刚的那个线程同时接到了参数13 //而后接收到参数的线程,却又有可能比先接收到参数的线程输出到窗口 hThreadArray[i] = CreateThread( NULL, 0, MyThreadFunction, lpParam, 0, &dwThreadIdArray[i]); } cout << "这里是主线程" << endl; for (int i = 0; i < MAX_THREADS; i++) { CloseHandle(hThreadArray[i]); } system("pause"); return 0; }
输出如图,毫无顺序性:
由此我们可以判定,被创建出来的线程以及创建这些线程的主线程是独立的执行体。他们被“迅速”创建之后,就开始“独立行动”,去“争抢”CPU。其实,线程是由操作系统按照一定的调度算法来决定谁先谁后执行。多线程实际上是异步的,它的目的就是快速的、交替的获取CPU的执行权,让用户以为这些线程是并行执行的。
我们对上边的例子稍作修改:
#include <iostream> #include <windows.h> using namespace std; #define MAX_THREADS 20 #define BUF_SIZE 255 DWORD dwAccessOrder = 0; DWORD WINAPI MyThreadFunction(LPVOID lpParam) { dwAccessOrder++; cout << "这是第" << dwAccessOrder << "个启动的线程!" << endl; return 0; } int main() { DWORD dwThreadIdArray[MAX_THREADS]; HANDLE hThreadArray[MAX_THREADS]; LPVOID lpParam = nullptr; for (int i = 0; i < MAX_THREADS; i++) { hThreadArray[i] = CreateThread( NULL, 0, MyThreadFunction, NULL, 0, &dwThreadIdArray[i]); } for (int i = 0; i < MAX_THREADS; i++) { CloseHandle(hThreadArray[i]); } system("pause"); return 0; }
输出如下结果:
当线程t1和t2都需要访问变量dwAccessOrder时,如果t1正在修改dwAccessOrder的值但是尚未完成,此时操作系统把执行权切换到了t2,此时t2要读取dwAccessOrder就得到了一个错误的值。因此,我们必须使用某种手段使得需要被多个线程共享的数据在同一时刻只能被一个线程访问。这种手段,叫做线程同步。
标签:
原文地址:http://www.cnblogs.com/predator-wang/p/5125590.html