关于windows的进程处理(五)

本文介绍了一种基于互斥量的进程同步控制方法,并通过示例代码展示了如何使用互斥量来确保进程间的正确同步,避免资源竞争。文章还探讨了不同互斥控制方式对程序运行的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基于互斥量(Mutual Exclusion)的同步控制

实现进程互斥的核心思想比较简单:进程在启动时首先检查当前系统是否已经存在有此进程的实例,如果没有,进程将成功创建并设置标识实例已经存在的标记。此后再创建进程时将会通过该标记而知晓其实例已经存在,从而保证进程在系统中只能存在一个实例。

HANDLE WINAPI CreateMutex(
  _In_opt_ LPSECURITY_ATTRIBUTES lpMutexAttributes,
  _In_     BOOL                  bInitialOwner,
  _In_opt_ LPCTSTR               lpName
);
BOOL WINAPI CloseHandle(
  _In_ HANDLE hObject
);
BOOL WINAPI ReleaseMutex(
  _In_ HANDLE hMutex
);

通过CreateMutex函数完成互斥量的申请和设定,如果反回NULL则表明,该互斥量已经被占用,因此申请失败,不可以运行,其他值则表明注册成功。用CloseHandle关闭互斥量,关闭后的互斥量就可以重新被注册了。通过ReleaseMutex完成一个的锁定,可以使WaitForSingleOibject得以结束。

#include "stdafx.h"
#include <Windows.h>
#include <process.h>

int num = 0;
CRITICAL_SECTION cs;
HANDLE hMutex = NULL;

unsigned WINAPI ThreadFun1(void *arg)
{
	int cnt = *(int*)arg;
	WaitForSingleObject(hMutex, INFINITE);
	for (int i = 0; i < cnt; i++)
	{
		num += 1;
		printf("Inc ");
		Sleep(10);
	}
	ReleaseMutex(hMutex);
	return 0;
}
unsigned WINAPI ThreadFun2(void *arg)
{
	int cnt = *(int*)arg;
	WaitForSingleObject(hMutex, INFINITE);
	for (int i = 0; i < cnt; i++)
	{
		num -= 1;
		printf("Dec ");
		Sleep(10);
	}
	ReleaseMutex(hMutex);
	return 0;
}

int main()
{
	int param = 50;
	HANDLE h[2];
	unsigned int hd[2];
	hMutex = CreateMutex(NULL, false, (LPCWSTR)"James");
	h[0]= (HANDLE)_beginthreadex(NULL, 0, ThreadFun1, &param, 0, &hd[0]);
	if (h[0] == 0)
	{
		printf("Can not create a thread 1.\n");
		return 0;
	}
	h[1] = (HANDLE)_beginthreadex(NULL, 0, ThreadFun2, &param, 0, &hd[1]);
	if (h[1] == 0)
	{
		printf("Can not create a thread 2.\n");
		return 0;
	}
	WaitForMultipleObjects(2, h, true, INFINITE);
	CloseHandle(hMutex);

	printf("The num is %d, and end of main.\n", num);
	return 0;
}

其运行结果如下:

Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc
Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc
Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec
Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec
Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec
The num is 0, and end of main.

从运行结果上我们可以看出,在Inc运行阶段,系统是被阻塞的,没有dec算法可以执行。我们调整一下控制位置,将控制放置到循环体内部,这样我们就会得到一个交替运行的工作过程,其代码和运行结果如下:

#include "stdafx.h"
#include <Windows.h>
#include <process.h>

int num = 0;
CRITICAL_SECTION cs;
HANDLE hMutex = NULL;

unsigned WINAPI ThreadFun1(void *arg)
{
	int cnt = *(int*)arg;
	for (int i = 0; i < cnt; i++)
	{
		WaitForSingleObject(hMutex, INFINITE);
		num += 1;
		printf("Inc ");
		ReleaseMutex(hMutex);
		Sleep(10);
	}
	return 0;
}
unsigned WINAPI ThreadFun2(void *arg)
{
	int cnt = *(int*)arg;
	for (int i = 0; i < cnt; i++)
	{
		WaitForSingleObject(hMutex, INFINITE);
		num -= 1;
		printf("Dec ");
		ReleaseMutex(hMutex);
		Sleep(10);
	}
	return 0;
}

int main()
{
	int param = 50;
	HANDLE h[2];
	unsigned int hd[2];
	hMutex = CreateMutex(NULL, false, (LPCWSTR)"James");
	h[0]= (HANDLE)_beginthreadex(NULL, 0, ThreadFun1, &param, 0, &hd[0]);
	if (h[0] == 0)
	{
		printf("Can not create a thread 1.\n");
		return 0;
	}
	h[1] = (HANDLE)_beginthreadex(NULL, 0, ThreadFun2, &param, 0, &hd[1]);
	if (h[1] == 0)
	{
		printf("Can not create a thread 2.\n");
		return 0;
	}
	WaitForMultipleObjects(2, h, true, INFINITE);
	CloseHandle(hMutex);

	printf("The num is %d, and end of main.\n", num);
	return 0;
}
Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc
Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc
Dec Inc Inc Dec Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc
Dec Inc Inc Dec Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc
Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc
The num is 0, and end of main.

 

转载于:https://my.oschina.net/u/2308182/blog/1421791

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值