使用互斥量(Mutex)进行windows 线程同步 跨进程线程同步

在windows,线程同步的方式比较多,这篇只是简单的介绍使用内核对象互斥量进行线程同步,互斥量Mutex为内核对象,使用方式原理和临界区CriticalSection差不多,临界区是基于用户空间进行线程同步的,只能进行同一个进程中线程的同步,不能跨进程,因为不是基于内核态的.下边是一个简单那的线程同步的例子.

编程步骤:

1,创建互斥量,2等候互斥量,3,释放互斥量,4,关闭互斥量,从等候互斥量到释放互斥量之间的代码块是原子执行的,一个线程等候到互斥量之后(A),在释放之前(B),其他线程是无法访问A-B之间的代码块的.这一点和临界区是一样的.在存在资源共享时,多线程同时处理共享数据,为了保证数据的完整性和安全性,可以采用这种方式进行同步.

主要用到的函数.

HANDLE CreateMutex(   //函数功能:创建互斥量
  LPSECURITY_ATTRIBUTES lpMutexAttributes,  // SD     互斥量安全属性,一般内核对象都会有此数据结构
  BOOL bInitialOwner,                       // initial owner    初始化的拥有者,谁初始拥有其执行权
  LPCTSTR lpName                            // object name 内核对象名字,跨进程通信时使用.
);
DWORD WaitForSingleObject(  //等候互斥量,
  HANDLE hHandle,        // handle to object  //互斥量句柄
  DWORD dwMilliseconds   // time-out interval  等候的超时时间
);
BOOL ReleaseMutex(   //释放互斥量,使其让其他线程拥有
  HANDLE hMutex   // handle to mutex  句柄
); 
// Mutex.cpp : 定义控制台应用程序的入口点。
//

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

HANDLE g_hMutex=NULL;

//线程函数
DWORD WINAPI ThreadFun1(LPVOID);
DWORD WINAPI  ThreadFun2(LPVOID);
DWORD WINAPI ThreadFun3(LPVOID);

int  _tmain(int argc, _TCHAR* argv[])
{
	//创建互斥对象
	g_hMutex=CreateMutex(NULL,FALSE,NULL);  //如果此处第二个参数为true,那就是主线程为互斥量的拥有者,这样,主线程不释放,其他线程只能等候.为false的话,谁先等候,谁先获取到,这个有操作系统决定.
	//创建线程
	DWORD threadID=0;
	HANDLE hThread[3]={0};
	hThread[0]=CreateThread(NULL,0,ThreadFun1,NULL,0,&threadID);
	hThread[1]=CreateThread(NULL,0,ThreadFun2,NULL,0,&threadID);
	hThread[2]=CreateThread(NULL,0,ThreadFun3,NULL,0,&threadID);
	WaitForMultipleObjects(3,hThread,TRUE,INFINITE);
	CloseHandle(g_hMutex);
	return 0;
}

VOID WINAPI Show(CHAR* str)
{
	//如果将等候和释放注释掉,则三个线程异步运行,各自独立运行,则每秒各自执行一次.
	//等待互斥
	WaitForSingleObject(g_hMutex,INFINITE);
	printf("------------%s----------------\n",str);
	Sleep(1000);
	//释放互斥
	ReleaseMutex(g_hMutex);
}

DWORD WINAPI  ThreadFun2( LPVOID param )
{
	while(1)
	{
		Show("线程2");
	}
	return 0;
}

DWORD WINAPI  ThreadFun1( LPVOID param )
{
	while(1)
	{
		Show("线程1");
	}
	return 0;
}

DWORD  WINAPI ThreadFun3( LPVOID param )
{
	while(1)
	{
		Show("线程3");
	}
	return 0;
}



图书馆登记和注销 要求:有一阅览室,读者进入时必须先在一张登记表上登记。该表中每个表项代表阅览室中的一个座位。读者离开时要消掉其登记信息。阅览室共有50 个座位。登记表每次仅允许一位读者进行登记或注销。 本实验由两个进程组成,分别是登陆和注销进程 使用到的函数和信号 HANDLE mutex; HANDLE empty; HANDLE full; 创建信号 HANDLE CreateSemaphore( __in_opt LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,// lpSemaphoreAttributes是信号的安全属性 可为NULL __in LONG lInitialCount,// lInitialCount是初始化的信号 __in LONG lMaximumCount,// lMaximumCount是允许信号增加到最大值 __in_opt LPCWSTR lpName//lpName是信号的名称 可为NULL ); 创建互斥信号 HANDLE CreateMutex(  LPSECURITY_ATTRIBUTES lpMutexAttributes, // 指向安全属性的指针 可为NULL  BOOL bInitialOwner, // 初始化互斥对象的所有者  LPCTSTR lpName // 指向互斥对象名的指针 ); 申请一个资源 WaitForSingleObject(HANDLE full,INFINITE); 释放资源 ReleaseSemaphore( __in HANDLE hSemaphore,// hSemaphore是要增加的信号句柄 __in LONG lReleaseCount,// lReleaseCount是增加的计数。 __out_opt LPLONG lpPreviousCount//lpPreviousCount是增加前的数值返回。 ); 释放互斥信号 BOOL ReleaseMutex(HANDLE hMutex); DWORD WaitForMultipleObjects( DWORD nCount, // number of handles in array CONST HANDLE *lpHandles, // object-handle array BOOL bWaitAll, // wait option DWORD dwMilliseconds // time-out interval );
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值