多线程编程学习(1)
1.创建一个线程
开关线程的API函数:
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes, //SD:线程安全属性,常置为NULL
SIZE_T dwStackSize, //initialstacksize:初始化栈的大小,可设置为0
LPTHREAD_START_ROUTINE lpStartAddress, //threadfunction:线程函数
LPVOID lpParameter, //threadargument:传入线程函数的参数,一般指向结构体,不需传递参数时为NULL
DWORD dwCreationFlags, //creationoption:线程属性,没有需要时置0
LPDWORD lpThreadId //threadidentifier:线程ID,如果为NULL则不返回线程ID
)
BOOL WINAPI CloseHandle(HANDLE hObject); //关闭线程
//----------------------------------------------------------------------------------------------------------------------------------------------
子线程函数体的调用格式:
DWORD WINAPI 函数名 (LPVOID lpParam)//在正常的函数体前加DWORD WINAPI,否则无法调用
//----------------------------------------------------------------------------------------------------------------------------------------------
接下来看一个代码,例子:
#include <iostream>
#include <windows.h>
using namespace std;
DWORD WINAPI multthread(LPVOID lpargs)
{
for (int i = 0; i < 10; i++)
{
cout << i << " son "<<endl; Sleep(200);
}
return 0;
}
int main()
{
int aa = 10;
HANDLE H1 = CreateThread(NULL, 0, multthread, NULL, 0, NULL);//创造一个线程
for (int i = 0; i < aa;i++)
{
cout << i << " parent "<<endl; Sleep(200);
}
CloseHandle(H1);
return 0;
}
从输出的结构来看,主程序和子线程已经交替的进行了输出:
但是,主线程和子线程的输出,为什么有时候在同一行,或者是空一行------
这是由于子线程和主线程在输出时,还未输出endl换行,子线程就抢先输出了,所以出现这种情况。
cout << i << " son "<<endl; Sleep(200);
换成:
cout << i << " son \n"; Sleep(200);
输出结果为:
2.还有一种方法可以解决上述输出问题,加一个互斥锁,保证某个线程能够独占资源
API函数为:
HANDLE WINAPI CreateMutex(
LPSECURITY_ATTRIBUTES lpMutexAttributes, //安全属性,常置为NULL
BOOL bInitialOwner, //创建Mutex时的当前线程是否拥有Mutex的所有权
LPCTSTR lpName //Mutex的名称)
DWORD WINAPI WaitForSingleObject(
HANDLE hHandle, //要获取的锁的句柄
DWORD dwMilliseconds //超时间隔,为INFINITE则表示无限等待
);
BOOL WINAPI ReleaseMutex(HANDLE hMutex); //释放
例子:
#include <iostream>
#include <windows.h>
using namespace std;
HANDLE H2 = NULL;//********************************************
DWORD WINAPI multthread(LPVOID lpargs)
{
for (int i = 0; i < 10; i++)
{
WaitForSingleObject(H2, INFINITE);//********************************
cout << i << " son "<<endl; Sleep(200);
ReleaseMutex(H2);//************************************
}
return 0;
}
int main()
{
int aa = 10;
HANDLE H1 = CreateThread(NULL, 0, multthread, NULL, 0, NULL);//创造一个线程
H2 = CreateMutex(NULL, FALSE, NULL);//创建互斥锁***********************
for (int i = 0; i < aa;i++)
{
WaitForSingleObject(H2, INFINITE);//*********************
cout << i << " parent "<<endl; Sleep(200);
ReleaseMutex(H2);//******************************
}
CloseHandle(H1);
return 0;
}
3.单个和多个参数的传入
下面代码向子线程中传入了一个int型的数,传入方式如下:
输出结果为:主程序运行完后,等待子线程运行结束。
5. 传入结构体
输出结果:
6.线程调用类中的函数
#include <thread>
#include <chrono>
#include <iostream>
using namespace std;
class thread_c
{
public:
void add_(int aa,int bb)
{
cout << "hello from class member function" <<aa<<" "<<bb<< endl;
}
private:
};
int main()
{
thread_c c;
thread t(&thread_c::add_,c,50,30);//类名+成员函数,实例化的类,输入的参数
this_thread::sleep_for(chrono::milliseconds(100));
t.detach();//线程后台运行
//t.join();//等待线程运行完后退出
return 0;
}
传入结构体
#include <thread>
#include <chrono>
#include <iostream>
using namespace std;
struct par
{
int aa;
int bb;
};
class thread_c
{
public:
void add_(par parm)
{
cout << "hello from class member function" <<parm.aa<<" "<<parm.bb<< endl;
}
private:
};
int main()
{
par parm;
parm.aa = 50;
parm.bb = 30;
thread_c c;
thread t(&thread_c::add_,c,parm);
this_thread::sleep_for(chrono::milliseconds(100));
t.detach();
return 0;
}