标签:lin 状态 先后 解锁 指定 无限 位置 object 句柄
在Windows平台下可以通过Windows的线程库来实现多线程编程。
对于多线程程序可以使用Visual Studio调试工具进行调试,也可以使用多核芯片厂家的线程分析调试工具进行调试。
Win32 API(了解Windows,代码小,效率高)
#include "stdio.h"
#include <windows.h>
#include <process.h>
#include <iostream>
#include <fstream>
using namespace std;
//使用_beginthread函数创建线程的例子。
void ThreadFunc1(PVOID param)
{
while (1)
{
Sleep(1000);
cout << " This is ThreadFunc1 " << endl;
}
}
void ThreadFunc2(PVOID param)
{
while (1)
{
Sleep(1000);
cout << " This is ThreadFunc2 " << endl;
}
}
//可以多次执行本程序,查看两个线程函数执行的顺序。
int main()
{
int i = 0;
_beginthread(ThreadFunc1, 0, NULL);
_beginthread(ThreadFunc2, 0, NULL);
Sleep(5000);
cout << "end" << endl;
return 0;
}
挂起与恢复函数原型
DWORD SuspendThread(HANDLE hThread);
挂起指定的线程(慎用,不处理同步对象)
如果函数执行成功,则线程的执行被终止
每次调用SuspendThread() 函数,线程将挂起计数器的值增1
DWORD ResumeThread(HANDLE hThread);
结束线程的挂起状态来执行这个线程
每次调用ResumeThread() 函数,线程将挂起计数器的值减1
若挂起计数器的值为0,则不会再减
#include "stdio.h"
#include <windows.h>
#include <iostream>
using namespace std;
//简单的多线程创建、执行、挂起、终止的程序例子。
DWORD WINAPI FunOne(LPVOID param) {
while (true)
{
Sleep(1000);
cout << "hello! ";
//cout<<"hello! "<<*((int*)param);
}
return 0;
}
DWORD WINAPI FunTwo(LPVOID param) {
while (true)
{
Sleep(1000);
cout << "world! ";
}
return 0;
}
//注意创建线程函数的第五个参数的运用。
//输入1和2数字,可以控制线程的启动和终止。
//注意连续输入1和2数字线程的运行情况。
//线程的终止函数。
int main(int argc, char* argv[])
{
int input = 0;
//创建线程。这里第四个参数值设为NULL也可以,因为线程函数里没有使用输入参数。
HANDLE hand1 = CreateThread(NULL, 0, FunOne, (void*)&input, CREATE_SUSPENDED, NULL);
HANDLE hand2 = CreateThread(NULL, 0, FunTwo, (void*)&input, CREATE_SUSPENDED, NULL);
while (true) {
cin >> input;
if (input == 1)
{
//恢复线程
ResumeThread(hand1);
ResumeThread(hand2);
}
if (input == 2)
{
//挂起线程
SuspendThread(hand1);
SuspendThread(hand2);
}
if (input == 0)
{
//终止线程
TerminateThread(hand1, 1);
TerminateThread(hand2, 1);
}
if (input == 9)
return 0;
};
return 0;
}
这样做可能会有一个问题,主线程结束时其他线程也就跟着结束了
#include "stdio.h"
#include <windows.h>
#include <iostream>
using namespace std;
//使用全局变量同步线程的例子。
//全局变量。
int globalvar = false;
DWORD WINAPI ThreadFunc(LPVOID pParam)
{
cout << " ThreadFunc " << endl;
Sleep(100);
//修改全局变量的值。
globalvar = true;
return 0;
}
DWORD WINAPI ThreadFunc1(LPVOID pParam)
{
while (1)
cout << " ThreadFunc111 " << endl;
return 0;
}
DWORD WINAPI ThreadFunc2(LPVOID pParam)
{
while (1)
cout << " ThreadFunc222 " << endl;
return 0;
}
//这种方式可能存在一些问题。
int main()
{
HANDLE hthread1 = CreateThread(NULL, 0, ThreadFunc1, NULL, 0, NULL);
HANDLE hthread2 = CreateThread(NULL, 0, ThreadFunc2, NULL, 0, NULL);
HANDLE hthread = CreateThread(NULL, 0, ThreadFunc, NULL, 0, NULL);
if (!hthread)
{
cout << "Thread Create Error ! " << endl;
CloseHandle(hthread);
}
bool b =SetThreadPriority(hthread,15);
cout<<GetThreadPriority(hthread1)<<endl;
cout<<GetThreadPriority(hthread2)<<endl;
cout<<GetThreadPriority(hthread)<<endl;
//循环判断全局变量的值。
while (!globalvar)
cout << "Thread while" << endl;
cout << "Thread exit" << endl;
return 0;
}
Thread while ThreadFunc111
ThreadFunc111
ThreadFunc111
ThreadFunc111 ThreadFunc222
ThreadFunc222
ThreadFunc222
ThreadFunc222
Thread while
Thread while
Thread while
Thread while
ThreadFunc222
ThreadFunc222
ThreadFunc111 Thread while
Thread while ThreadFunc222
ThreadFunc111
Thread exit
ThreadFunc111 ThreadFunc222
ThreadFunc222 ThreadFunc111
ThreadFunc111
ThreadFunc222
ThreadFunc111
事件是WIN32提供的最灵活的线程间同步方式。
事件存在两种状态:
激发状态(signaled or true)
未激发状态(unsignal or false)
事件可分为两类:
手动设置:这种对象只能用程序来手动设置,在需要该事件或者事件发生时,采用SetEvent及ResetEvent来进行设置。
SetEvent只有一个参数,该参数指定了事件对象的句柄值,若事件成功激发,返回TRUE;
ResetEvent函数将事件对象恢复到最初的非激发状态,只有一个参数,成功后返回真
自动恢复:一旦事件发生并被处理后,自动恢复到没有事件状态,不需要再次设置。
例子:有三个线程
主线程、读线程ReadThread、写线程WriteThread
读线程ReadThread必须在写线程WriteThread 的写操作完成之后才能进行读操作
主线程必须在读线程ReadThread 的读操作完成后才结束
定义两个事件对象evRead,evFinish
evRead由写线程WriteThread用于通知读线程ReadThread 进行读操作
evFinish由读线程ReadThread用于通知主线程读操作已经结束
#include "stdio.h"
#include <windows.h>
#include <iostream>
using namespace std;
//**使用事件机制同步线程的例子。
//两个事件。
HANDLE evRead, evFin;
HANDLE evWrite;
void ReadThread(LPVOID param)
{
//等待读事件。
WaitForSingleObject(evRead, INFINITE);
cout << "Reading" << endl;
//ResetEvent(evRead);//evRead为手动恢复类型时打开
SetEvent(evWrite);
WaitForSingleObject(evRead, INFINITE);
cout << "Reading11111" << endl;
//激活结束事件。
SetEvent(evFin);
}
void WriteThread(LPVOID param)
{
cout << "Writing" << endl;
//激活读事件。
SetEvent(evRead);
WaitForSingleObject(evWrite, INFINITE);
cout << "Writing11111" << endl;
SetEvent(evRead);
}
int main(int argc, char* argv[])
{
//创建两个事件,注意事件参数的含义。
evRead = CreateEvent(NULL, FALSE, FALSE, NULL);
evFin = CreateEvent(NULL, FALSE, FALSE, NULL);
evWrite = CreateEvent(NULL, FALSE, FALSE, NULL);
//evRead = CreateEvent (NULL ,TRUE ,FALSE ,NULL) ;//修改第二个参数为TRUE
//evFin = CreateEvent (NULL ,TRUE ,FALSE ,NULL) ;//修改第二个参数为TRUE
//evWrite = CreateEvent (NULL ,TRUE ,FALSE ,NULL) ;//修改第二个参数为TRUE
_beginthread(ReadThread, 0, NULL);
_beginthread(WriteThread, 0, NULL);
//等待结束事件。
WaitForSingleObject(evFin, INFINITE);
cout << "The Program is End" << endl;
return 0;
}
#include "stdio.h"
#include <windows.h>
#include <iostream>
#include <process.h>
#include <iostream>
#include <fstream>
using namespace std;
//**使用临界区机制同步线程。
int total = 100;
HANDLE evFin[2];
CRITICAL_SECTION cs;//临界区。
//可以去掉临界区机制,查看是否出现错误。(需要辅助sleep函数)
void WithdrawThread1(LPVOID param)
{
EnterCriticalSection(&cs);//进入临界区
if (total - 90 >= 0)
{//Sleep(100);
total -= 90;
cout << "You withdraw 90" << endl;
}
else
cout << "You do not have that much money" << endl;
LeaveCriticalSection(&cs);//退出临界区
SetEvent(evFin[0]);
}
void WithdrawThread2(LPVOID param)
{
EnterCriticalSection(&cs);//进入临界区
if (total - 20 >= 0)
{
total -= 20;
cout << "You withdraw 20" << endl;
}
else
cout << "You do not have that much money" << endl;
LeaveCriticalSection(&cs);//退出临界区
//LeaveCriticalSection(&cs) ;
SetEvent(evFin[1]);
}
int main(int argc, char* argv[])
{
evFin[0] = CreateEvent(NULL, FALSE, FALSE, NULL);
evFin[1] = CreateEvent(NULL, FALSE, FALSE, NULL);
InitializeCriticalSection(&cs);//初始化临界区。
_beginthread(WithdrawThread1, 0, NULL);//创建线程顺序影响执行的结果。
_beginthread(WithdrawThread2, 0, NULL);
//_beginthread(WithdrawThread1 , 0 , NULL) ;
int id = WaitForMultipleObjects(2, evFin, TRUE, INFINITE);//等待两个事件都激活。
cout << "句柄数组中的索引:" << id << endl;
DeleteCriticalSection(&cs);//删除临界区
cout << total << endl;
return 0;
}
先1后2
先2后1
#include "stdio.h"
#include <windows.h>
#include <iostream>
#include <process.h>
#include <iostream>
#include <fstream>
using namespace std;
//**互斥量的使用方法。
#define THREAD_INSTANCE_NUMBER 3
LONG g_fResourceInUse = FALSE;
LONG g_lCounter = 0;
DWORD ThreadProc(void* pData) {
int ThreadNumberTemp = (*(int*)pData);
HANDLE hMutex;
if ((hMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, "Mutex.Test")) == NULL) {
cout << "Open Mutex error!" << endl;
}
//cout << "ThreadProc is running hMutexxxxxxx!!" << ThreadNumberTemp <<endl;
WaitForSingleObject(hMutex, INFINITE);//获取互斥量。
cout << "ThreadProc is running!!" << ThreadNumberTemp << endl;
cout << "ThreadProc gets the mutex-" << ThreadNumberTemp << endl;
ReleaseMutex(hMutex);//释放互斥量。
CloseHandle(hMutex);
return 0;
}
int main(int argc, char* argv[])
{
int i;
DWORD ID[THREAD_INSTANCE_NUMBER];
HANDLE h[THREAD_INSTANCE_NUMBER];
HANDLE hMutex;
if ((hMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, "Mutex.Test")) == NULL) {
if ((hMutex = CreateMutex(NULL, FALSE, "Mutex.Test")) == NULL) //注意第二个参数,当前线程是否拥有创建的锁
{
cout << "Create Mutex error!" << endl;
return 0;
}
}
//ReleaseMutex(hMutex); //CreateMutex函数第二参数为TRUE时打开
//获取信号量的位置不同,将产生不同的结果。
//WaitForSingleObject(hMutex,INFINITE);
for (i = 0; i < THREAD_INSTANCE_NUMBER; i++)
{
WaitForSingleObject(hMutex, INFINITE);//获取互斥量。本线程可重复获取,但解锁时需释放相同的次数。
h[i] = CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)ThreadProc,
(void*)&ID[i],
0,
&(ID[i]));
//WaitForSingleObject(hMutex,INFINITE);//演示重复获取互斥量
if (h[i] == NULL)
cout << "CreateThread error" << ID[i] << endl;
else
cout << "CreateThread: " << ID[i] << endl;
ReleaseMutex(hMutex);
//Sleep(1000);
}
//ReleaseMutex(hMutex);//ReleaseMutex(hMutex);ReleaseMutex(hMutex);//演示释放重复获取的互斥量
WaitForMultipleObjects(THREAD_INSTANCE_NUMBER, h, TRUE, INFINITE);
cout << "Close the Mutex Handle! " << endl;
CloseHandle(hMutex);
return 0;
}
// exa7.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <windows.h>
#include <iostream>
using namespace std;
//**使用信号量机制同步线程。
#define THREAD_INSTANCE_NUMBER 3
DWORD foo(void * pData) {
int ThreadNumberTemp = (*(int*) pData);
HANDLE hSemaphore;
if ((hSemaphore = OpenSemaphore(SEMAPHORE_ALL_ACCESS, FALSE, "Semaphore.Test")) == NULL) {
cout << "Open Semaphore error!" << endl;
}
WaitForSingleObject(hSemaphore,INFINITE);//获取信号量。
cout << "foo is running!!!" << ThreadNumberTemp << endl;
cout << "foo gets the semaphore-" << ThreadNumberTemp<< endl;
ReleaseSemaphore(hSemaphore, 1, NULL);//释放一个单位的信号量
CloseHandle(hSemaphore);
return 0;
}
int main(int argc, char* argv[])
{
int i;
DWORD ThreadID[THREAD_INSTANCE_NUMBER];
HANDLE hThread[THREAD_INSTANCE_NUMBER];
HANDLE hSemaphore;
if ((hSemaphore = CreateSemaphore(NULL,1,1, "Semaphore.Test")) == NULL ) {
cout << "Create Semaphore error!" << endl;
return 0;
}
//与互斥量一样,这里获取信号量的位置不同,会产生不同的结果。
for (i=0;i<THREAD_INSTANCE_NUMBER;i++)
{
WaitForSingleObject(hSemaphore,INFINITE);//获取信号量。不可重入。
hThread[i] = CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE) foo,
(void *)&ThreadID[i],
0,
&(ThreadID[i]));
if (hThread[i] == NULL)
cout << "CreateThread error" << ThreadID[i] << endl;
else
cout << "CreateThread: " << ThreadID[i] << endl;
ReleaseSemaphore(hSemaphore, 1, NULL);
}
WaitForMultipleObjects(THREAD_INSTANCE_NUMBER,hThread,TRUE,INFINITE);
cout << "Close the Semaphore Handle! " << endl;
CloseHandle(hSemaphore);
return 0;
}
标签:lin 状态 先后 解锁 指定 无限 位置 object 句柄
原文地址:https://www.cnblogs.com/wuliaojava/p/11759787.html