线程的传参
#include<Windows.h>
#include<process.h>
#include<stdio.h>
int g_iValue = 0;
UINT _stdcall ThreadProc(LPVOID arg) {
int va = *(int*)arg;//可以通过修改这个值的类型实现传不同的参
printf("va:%d\n", va);
for (int i = 0;i < 5;i++) {
g_iValue++;
printf("g_iValue = %d\n", g_iValue);
}
return 1;
}
int main(int argc, char* argv[])
{
HANDLE hArray[2] = { 0 };
unsigned tid = 0;
int data = 1;
hArray[0] = (HANDLE)_beginthreadex(NULL, 0,ThreadProc, &data,0,&tid);
hArray[1] = (HANDLE)_beginthreadex(NULL, 0, ThreadProc, &data, 0, &tid);
WaitForMultipleObjects(2, hArray, TRUE, INFINITE);
CloseHandle(hArray[0]);
CloseHandle(hArray[1]);
return 0;
}
通过使用结构体来实现一次传多个参
#include<Windows.h>
#include<process.h>
#include<stdio.h>
typedef struct _Data {
int data;
char *s;
}Data,*PData;
int g_iValue = 0;
UINT _stdcall ThreadProc(LPVOID arg) {
Data* p = (Data*)arg;
printf("data:%d ,%s\n", p->data,p->s);
for (int i = 0;i < 5;i++) {
g_iValue++;
printf("g_iValue = %d\n", g_iValue);
}
return 1;
}
int main(int argc, char* argv[])
{
HANDLE hArray[2] = { 0 };
unsigned tid = 0;
Data dat = { 10,"hello" };
hArray[0] = (HANDLE)_beginthreadex(NULL, 0,ThreadProc, &dat,0,&tid);
hArray[1] = (HANDLE)_beginthreadex(NULL, 0, ThreadProc, &dat, 0, &tid);
WaitForMultipleObjects(2, hArray, TRUE, INFINITE);
CloseHandle(hArray[0]);
CloseHandle(hArray[1]);
return 0;
}
线程执行函数长期执行
bool bwillexit = FALSE;
UINT _stdcall ThreadProc(LPVOID arg) {
while(bwillexit == FALSE){
//bwillexit = TRUE
}
}
多线程安全
程序的一致性,要对程序进行加锁或者使用局部变量,Windows为了确保安全,有互斥,同步和原子操作的机制
互斥(竞争)
CRITICAL_SECTION 临界区加锁,两把锁时一定要按照顺序拿锁,否则容易造成死锁。只能用在同一个进程。
struct RTL_CRITICAL_SECTION{
RTL_CRITICAL_SECTION_DEBUG DebugInfo;
LONG LockCount;
LONG RecursionCount;
HANDLE OwningThread;
HANDLE LockSemaphore;
ULONG_PTR SpenCount;
}
CRITICAL_SECTION cs;//定义一个临界区
InitializeCriticalSection(&cs);//对临界区初始化
EnterCriticalSection(&cs);//加锁
//访问全局资源
LeaveCriticalSection(&cs);//放锁
DeleteCriticalSection(&cs);//对临界区清空
应用
#include<Windows.h>
#include<process.h>
#include<stdio.h>
int g_iValue = 0;
CRITICAL_SECTION cs;//定义全局资源后马上定义一把锁
UINT _stdcall ThreadProc(LPVOID arg) {
for (int i = 0;i < 5;i++) {
EnterCriticalSection(&cs);//加锁
g_iValue++;
printf("g_iValue = %d\n", g_iValue);
LeaveCriticalSection(&cs);//放锁
}
return 1;
}
int main(int argc, char* argv[])
{
HANDLE hArray[2] = { 0 };
InitializeCriticalSection(&cs);//初始化临界区
unsigned tid = 0;
hArray[0] = (HANDLE)_beginthreadex(NULL, 0,ThreadProc, NULL,0,&tid);
hArray[1] = (HANDLE)_beginthreadex(NULL, 0, ThreadProc, NULL, 0, &tid);
WaitForMultipleObjects(2, hArray, TRUE, INFINITE);
CloseHandle(hArray[0]);
CloseHandle(hArray[1]);
DeleteCriticalSection(&cs);//删除锁
return 0;
}
Mutex 线程结束之后会自动放锁 可用于跨进程的线程锁
HANDLE hMutex = NULL;
hMutex = CreateMutex(NULL, FALSE, NULL);
WaitForSingleObject(hMutex, INFINITE);
//WaitForMultipleObjects(2, hArray, TRUE, INFINITE);
ReleaseMutex(hMutex);
CloseHandle(hMutex);
应用
#include<windows.h>
#include<process.h>
#include<stdio.h>
int a = 0;
HANDLE hMutex = NULL;
UINT _stdcall ThreadProc1(LPVOID arg) {
WaitForSingleObject(hMutex, INFINITE);
for (int i = 0;i < 5;i++) {
a++;
printf("a1 = %d\n", a);
}
ReleaseMutex(hMutex);
return 1;
}
UINT _stdcall ThreadProc2(LPVOID arg) {
WaitForSingleObject(hMutex, INFINITE);
for (int i = 0;i < 5;i++) {
a++;
printf("a2 = %d\n", a);
}
ReleaseMutex(hMutex);
return 1;
}
int main(int argc, char* argv[])
{
HANDLE hArray[2] = { 0 };
unsigned tid = 0;
hMutex = CreateMutex(NULL, FALSE, NULL);
hArray[0] = (HANDLE)_beginthreadex(NULL, 0, ThreadProc1, NULL, 0, &tid);
hArray[1] = (HANDLE)_beginthreadex(NULL, 0, ThreadProc2, NULL, 0, &tid);
WaitForMultipleObjects(2, hArray, TRUE, INFINITE);
CloseHandle(hArray[0]);
CloseHandle(hArray[1]);
CloseHandle(hMutex);
return 0;
}
同步(协助)
EVENT
HANDLE Event = NULL;
Event = CreateEvent(NULL,FALSE,FALSE,NULL);
SetEvent(Event);//发送信号
WaitForSingleObject(Event,INFINITE);//等待接收信号
CloseHandle(Event);
应用
#include<windows.h>
#include<process.h>
#include<stdio.h>
HANDLE Event = NULL;
UINT _stdcall ThreadProc1(LPVOID arg) {
printf("Waiting\n");
WaitForSingleObject(Event, INFINITE);
printf("Begin\n");
return 1;
}
UINT _stdcall ThreadProc2(LPVOID arg) {
for (int i = 0;i < 10;i++) {
printf("%d\n", i);
}
SetEvent(Event);
return 1;
}
int main(int argc, char* argv[])
{
HANDLE hArray[2] = { 0 };
unsigned tid = 0;
Event = CreateEvent(NULL, FALSE, FALSE, NULL);
hArray[0] = (HANDLE)_beginthreadex(NULL, 0, ThreadProc1, NULL, 0, &tid);
hArray[1] = (HANDLE)_beginthreadex(NULL, 0, ThreadProc2, NULL, 0, &tid);
WaitForMultipleObjects(2, hArray, TRUE, INFINITE);
CloseHandle(hArray[0]);
CloseHandle(hArray[1]);
CloseHandle(Event);
return 0;
}
原子操作
InterlockedExchange:g_a=b
InterlockedIncrement:g_a++
InterlockedIncrement(i);//i++
指在执行过程中不会被打断,一次性完成,不会执行一半切换出去
应用
#include<windows.h>
#include<process.h>
#include<stdio.h>
int g_iValue = 0;
UINT _stdcall ThreadProc(LPVOID arg) {
for (int i = 0;i < 5;i++) {
InterlockedIncrement((LONG*)&g_iValue);
printf("g_iValue = %d\n", g_iValue);
}
return 1;
}
int main(int argc, char* argv[])
{
HANDLE hArray[2] = { 0 };
unsigned tid = 0;
hArray[0] = (HANDLE)_beginthreadex(NULL, 0,ThreadProc, NULL,0,&tid);
hArray[1] = (HANDLE)_beginthreadex(NULL, 0, ThreadProc, NULL, 0, &tid);
WaitForMultipleObjects(2, hArray, TRUE, INFINITE);
CloseHandle(hArray[0]);
CloseHandle(hArray[1]);
return 0;
}