1、在Windows上创建线程
通过窗口句柄创建线程:
参数说明:
-
参数1:
lpThreadAttributes
表示线程内核对象的安全属性,一般传入NULL表示使用默认设置。 -
:参数 2:
dwStackSize
表示线程栈空间大小。传入0表示使用默认大小(1MB)。 -
:参数3:
lpStartAddress
表示新线程所执行的线程函数地址,多个线程可以使用同一个函数地址(函数名)。 -
参数4:
lpParameter
是传给线程函数的参数。传入值为一个空指针,运用类型强转的方法,可以传入多个参数。 -
:参数5:
dwCreationFlags
指定额外的标志来控制线程的创建,为0表示线程创建之后立即就可以进行调度,如果为CREATE_SUSPENDED则表示线程创建后暂停运行,这样它就无法调度,直到调用ResumeThread()。 -
:参数6:
lpThreadId
将返回线程的ID号,传入NULL表示不需要返回该线程ID号
返回值
-
线程创建成功返回新线程的句柄,失败返回NULL
#include<iostream>
#include<windows.h>
using namespace std;
DWORD WINAPI myThread(LPVOID lpParameter);
DWORD WINAPI myThread1(LPVOID lpParameter);
typedef struct{
int paraInt;
float paraFloat;
}Param;
int main()
{
HANDLE h;
HANDLE h1;
Param lap;
lap.paraFloat = 0.5;
lap.paraInt = 5;
int a = 10;
h = CreateThread(NULL, 0, myThread, (void*)&a, 0, NULL);
h1 = CreateThread(NULL, 0, myThread1, (void*)&lap, 0, NULL);
system("pause");
//关闭线程句柄对象
CloseHandle(h);
CloseHandle(h1);
return 0;
}
DWORD WINAPI myThread(LPVOID lpParameter)
{
cout << "线程1正在运行" << endl;
cout << lpParameter << endl;
return 0;
}
DWORD WINAPI myThread1(LPVOID lpParameter)
{
cout << "线程2正在运行" << endl;
Param *p = (Param *)lpParameter;
cout << p->paraFloat << endl;
cout << p->paraInt << endl;
return 0;
}
2、MFC创建线程
#include<iostream>
#include<windows.h>
#include<afxwin.h>
using namespace std;
DWORD WINAPI myThread(LPVOID lpParameter);
typedef struct{
int paraInt;
float paraFloat;
}Param;
void WaitForFinish(HANDLE handle)
{
try
{
while (true)
{
if (handle == NULL)
return;
DWORD result = MsgWaitForMultipleObjects(1, &handle, FALSE, INFINITE, QS_ALLINPUT);
if (result == (WAIT_OBJECT_0))
{
CloseHandle(handle);
handle = NULL;
break;
}
else
{
MSG msg;
PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
DispatchMessage(&msg);
}
}
}
catch (...)
{
}
}
int main()
{
int a = 10;
CWinThread* threadProc1 = NULL;
threadProc1 = AfxBeginThread((AFX_THREADPROC)myThread, &a);//参数2表示传入的参数
threadProc1->m_bAutoDelete = false;
threadProc1->ResumeThread();
WaitForFinish(threadProc1->m_hThread);//等待线程结束
system("pause");
return 0;
}
DWORD WINAPI myThread(LPVOID lpParameter)
{
cout << "线程1正在运行" << endl;
cout << lpParameter << endl;
return 0;
}
3、Qt中线程类
thread.h
#pragma execution_character_set("utf-8")
#include<QThread>
class Thread : public QThread//继承Qt库中的线程类
{
Q_OBJECT
public:
......//定义线程的成员变量
Thread();
void setParam(.....);//需要传入的参数,此处将借到的参数复值给成员变量
protected:
void run();//线程启动后,调用的方法
private:
int i;
};
thread.cpp
#include "thread.h"
#include <QDebug>
Thread::Thread()
{
}
//线程需要的参数
void Thread::setParam(......)
{
......//成员变量接收外部传入的参数
}
//线程实现
void Thread::run()
{
......//线程具体实现方法
main.cpp
#include"thread.h"
int main()
{
Thread thread;
thread.start();//启动线程
}
注:Qt中创建线程,最好不要传入UI界面的控件,通过控间直接去刷新界面,最好的方法时由线程中发送信号,由UI类写槽函数。具体运用实例见Qt常用类博文
3、Windows下互斥锁的运用
//为MFC所用
//创建锁 参数2:表示互斥锁创建出来后是否被当前线程持有 参数3:互斥锁的名字,如果是nullptr,则互斥锁是匿名的
HANDLE hMutex = CreateMutex(nullptr, FALSE, nullptr);
//持有, 参数1为互斥锁句柄时,函数作用为等待其他持有者释放,参数2:等待的时间(单位:毫秒),如果该参数为INFINITE,则该函数会一直等待下去。
WaitForSingleObject(hMutex, dwTimeout);
//释放 让当前线程“放开”一个互斥锁(不持有它了),以便让其他线程可以持有它
//参数1:锁的句柄
ReleaseMutex(hMutex);
4、临界区的运用(类似互斥锁)
CRITICAL_SECTION m_Camera_Section; //申明一个临界区
InitializeCriticalSection(&m_Camera_Section); //初始化临界区
EnterCriticalSection(&m_Camera_Section); //进入临界区
LeaveCriticalSection(&m_Camera_Section); //退出临界区
5、读写锁的运用
进入读状态,其他线程可以继续读取,但是不能写入数据。进入写状态,其他线程不能读取也不能写入数据
SRWLOCK rwLock;//定义读写锁
InitializeSRWLock(&rwLock);//初始化读写锁
AcquireSRWLockExclusive(&rwLock);//进入写状态
ReleaseSRWLockExclusive(&rwLock);//退出写状态
AcquireSRWLockShared(&rwLock);//进入读状态
ReleaseSRWLockShared(&rwLock);//退出读状态