线程同步四种方式

四种进程或线程同步互斥的控制方法
      1、临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。 
  2、互斥量:为协调共同对一个共享资源的单独访问而设计的。 
        以上两种只能实现线程互斥,不能实现线程同步,涉及到同步,则需要使用下面两种方法
  3、信号量:为控制一个具有有限数量用户资源而设计。 
  4、事 件:用来通知线程有一些事件已发生,从而启动后继任务的开始。 

#include <iostream>
#include <Windows.h>
using namespace std;

//使用互斥对象Mutex来控制线程同步
DWORD WINAPI Fun1Proc(LPVOID lpParameter);
DWORD WINAPI Fun2Proc(LPVOID lpParameter);

int index = 0;
volatile int tickets = 10;
HANDLE hMutex;  //创建的互斥量

void main()
{
	//创建互斥对象,TRUE代表主程序用于互斥对象,线程ID设置为调用线程的ID,
    //递归计数器设置为1,由于ID是非0的,互斥对象开始时不发出通知信号。
	//FALSE互斥对象ID和递归计数器均被设置为0,即互斥对象没有被任何线程所用于,
	//因此它要发出通知信号、
	hMutex = CreateMutex(NULL, TRUE, "tickets");

	if (hMutex)
	{
		if (ERROR_ALREADY_EXISTS == GetLastError())
		{
			cout << "only one instance can run!" << endl;
			return;
		}
	}
	ReleaseMutex(hMutex);

	//创建线程
	HANDLE hThread1;
	HANDLE hThread2;
	
	hThread1 = CreateThread(NULL, 0, Fun1Proc, NULL, 0, NULL);
	hThread2 = CreateThread(NULL, 0, Fun2Proc, NULL, 0, NULL);

	CloseHandle(hThread1);
	CloseHandle(hThread2);

	//通过调用一个等待函数,并传递负责保护资源的互斥对象的句柄,
	//线程就能获得共享资源的访问权。
	WaitForSingleObject(hMutex, INFINITE);
	cout << "Main Thread!" << endl;
	ReleaseMutex(hMutex);
	Sleep(4000);

	system("pause");
	
}

DWORD WINAPI Fun1Proc(LPVOID lpParameter)
{
	while (true)
	{
		//请求事件对象
		WaitForSingleObject(hMutex, INFINITE);
		if (tickets > 0)
		{
			Sleep(0);
			cout << "thread1 sell ticket: " << tickets-- << endl;
		}
		else
			break;
		ReleaseMutex(hMutex);
	}
	return 0;
}

DWORD WINAPI Fun2Proc(LPVOID lpParameter)
{
	while (true)
	{
		WaitForSingleObject(hMutex, INFINITE);
		if (tickets > 0)
		{
			Sleep(0);
			cout << "thread2 sell ticket: " << tickets-- << endl;
		}
		else
			break;
		ReleaseMutex(hMutex);
	}
	return 0;
}
//信号量方式

#include <Windows.h>
#include <iostream>
using namespace std;

const int MAX_SEM_COUNT = 10;
const int THREADCOUNT = 12;

HANDLE ghSemaphore; //信号量

DWORD WINAPI ThreadProc(LPVOID);

int main()
{
	HANDLE aThread[THREADCOUNT];
	DWORD ThreadID;
	int i;

	//创建一个信号量,用MAX_SEM_COUNT初始化信号最大数量

	ghSemaphore = CreateSemaphore(
		NULL,   //默认的安全属性
		MAX_SEM_COUNT,  //初始化值
		MAX_SEM_COUNT,  //最多的信号量
		NULL);          //未命名的信号量

	if (ghSemaphore == NULL)
	{
		cout << "CreateSemaphore error: " << GetLastError() << endl;
		return 1;
	}

	//创建工作线程
	for (int i = 0; i < THREADCOUNT; i++)
	{
		aThread[i] = CreateThread(
			NULL,
			0,
			ThreadProc,
			NULL, 0,
			&ThreadID);    //线程ID
		if (aThread[i] == NULL)
		{
			cout << "CreateThread error: " << GetLastError() << endl;
			return 1;
		}
	}

	//等待所有的线程终止
	WaitForMultipleObjects(THREADCOUNT, aThread, TRUE, INFINITE);

	//关闭线程和信号量句柄
	Sleep(1000);
	for (int i = 0; i < THREADCOUNT; i++)
		CloseHandle(aThread[i]);
    CloseHandle(ghSemaphore);

	system("pause");
	return 0;
}

DWORD WINAPI ThreadProc(LPVOID)
{
	DWORD dwWaitResult;
	BOOL bContinue = TRUE;

	while (bContinue)
	{
		dwWaitResult = WaitForSingleObject(ghSemaphore, 0);

		switch (dwWaitResult)
		{
		case WAIT_OBJECT_0:
			cout << "Thread " << GetCurrentThreadId() << ": wait succeeded" << endl;
			bContinue = FALSE;

			Sleep(5);
			//释放信号量
			if (! ReleaseSemaphore(ghSemaphore, 1, NULL))
			{
				cout << "ReleaseSemaphore error: " << GetLastError() << endl;
			}
			break;
		case WAIT_TIMEOUT:
			cout << "Thread " << GetCurrentThreadId() << ": wait timed out" << endl;
			break;
		}
	}
	return 1;
}

#include <Windows.h>
#include <iostream>
using namespace std;

//利用事件控制线程同步
DWORD WINAPI Fun1Proc(LPVOID lpParameter);
DWORD WINAPI Fun2Proc(LPVOID lpParameter);

int tickets = 100;
HANDLE g_hEvent;     //用于表示同步事件

void main()
{
	//第一个FALSE:创建一个自动重置事件;如果为TRUE,则是人工重置事件
	//第二个FALSE:用于指明该事件是要初始化为已通知状态(TRUE)还是未通知状态(FALSE)
	//以下为创建一个自动重置事件,且初始状态为未通知事件
	g_hEvent = CreateEvent(NULL, FALSE, FALSE, "tickets");
	if (g_hEvent)
	{
		if (ERROR_ALREADY_EXISTS == GetLastError())
		{
			cout << "only one instance can run! " << endl;
			return ;
		}
	}
	SetEvent(g_hEvent);  //将事件设置为已通知状态

	HANDLE hThread1;
	HANDLE hThread2;

	hThread1 = CreateThread(NULL, 0, Fun1Proc, NULL, 0, NULL);
	hThread2 = CreateThread(NULL, 0, Fun2Proc, NULL, 0, NULL);
	CloseHandle(hThread1);
	CloseHandle(hThread2);

	Sleep(4000);
	CloseHandle(g_hEvent);
	system("pause");
}

DWORD WINAPI Fun1Proc(LPVOID lpParameter)
{
	while (true)
	{
		WaitForSingleObject(g_hEvent, INFINITE);
		if (tickets > 0)
		{
			Sleep(1);
			cout << "thread1 sell ticket: " << tickets-- << endl;
			SetEvent(g_hEvent);
		}
		else
		{
			SetEvent(g_hEvent);
			break;
		}
	}
	return 0;
}

DWORD WINAPI Fun2Proc(LPVOID lpParameter)
{
	while (true)
	{
		WaitForSingleObject(g_hEvent, INFINITE);
		if (tickets > 0)
		{
			Sleep(1);
			cout << "thread2 sell ticket: " << tickets-- << endl;
			SetEvent(g_hEvent);
		}
		else
		{
			SetEvent(g_hEvent);
			break;
		}
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
线程同步四种方式是: 1. 互斥锁(Mutex):通过对共享资源加锁,保证在同一时刻只有一个线程可以访问该资源,其他线程需要等待锁释放后才能访问。这种方式可以避免多个线程同时修改共享资源导致的数据不一致问题。 2. 信号量(Semaphore):通过设置一个计数器,控制同时访问共享资源的线程数量。当计数器不为零时,线程可以访问资源;当计数器为零时,线程需要等待其他线程释放资源后才能访问。信号量可以用于控制线程的并发数量。 3. 事件(Event):通过一个或多个标志来通知线程是否可以继续执行。线程可以等待事件的触发,一旦触发,线程就可以继续执行。事件可以用于线程之间的通信和同步。 4. 条件变量(Condition Variable):用于线程之间的通信和同步,一个线程等待某个条件满足时可以阻塞自己,直到其他线程通知该条件已经满足,然后线程可以继续执行。条件变量通常和互斥锁一起使用,以实现线程之间的同步和协作。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [线程同步四种方式](https://blog.csdn.net/chanlp129/article/details/125357577)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *3* [[面试]进程同步的四种方法](https://blog.csdn.net/wuhuagu_wuhuaguo/article/details/78591330)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值