详细简单的win中P,V操作(司机、售票员)C语言

如果还不知道创建子进程,参考:
win中创建进程

正文开始:
c语言windows环境下::

1.<windows.h>中有信号量创建的函数和模拟PV操作的函数:

创建信号量
HANDLE CreateSemaphore(
 LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, // 安全属性指针
 LONG lInitialCount, // 初始计数
 LONG lMaximumCount, // 最大计数
 LPCTSTR lpName // 对象名指针
);
参数lMaximumCount是一个有符号32位值,定义了允许的最大资源计数,最大取值不能超过4294967295。
lpName参数可以为创建的信号量定义一个名字,由于其创建的是一个内核对象,因此在其他进程中可以通过该名字而得到此信号量,这个名字非常重要,你在其他进程中可以直接通过这个名字找到这个信号量。
打开信号量
HANDLE OpenSemaphore(
 DWORD dwDesiredAccess, // 访问标志
 BOOL bInheritHandle, // 继承标志
 LPCTSTR lpName // 信号量名!!!!!!!!!
);
这里就是在其他进程中通过信号量名字进行索引!!!!
释放信号量
BOOL ReleaseSemaphore(
 HANDLE hSemaphore, // 信号量句柄
 LONG lReleaseCount, // 计数递增数量
 LPLONG lpPreviousCount // 先前计数
);
等待信号量(相当于P操)
WaitForSingleObject()//等一个
WaitForMultipleObjects()//等多个
主要用在试图进入共享资源的线程函数入口处,主要用来判断信号量的当前可用资源计数是否允许本线程的进入。
注意:实际上的P操作是在进程得到这个信号量的时候就完成的,并不是上面两个相当于P操作的函数完成的。

2.下面来模拟PV操作

P操作:WaitForSingleObject(信号量引用,等待时间)
V操作:ReleaseSemaphore(信号量引用,加的值,原始值)

例如现在有一个s1信号量:

WaitForSingleObject(s1,INFINITE);//等待无限时长
ReleaseSemaphore(s1,1NULL);//第三个参数原始值不用管

3.实现司机和售票员的进程通信代码思路:

1.在司机进程中创建售票员进程,然后通过PV操作进行通信
2.信号量在哪定义呢?在司机里面,并且定义的时候尽量取个名字,这样在售票员子进程中可以直接通过名字获取。

CODE:

//司机进程代码 

#include<stdio.h>
#include<windows.h>

HANDLE S1 = CreateSemaphore(NULL, 0, 1, "driver_s");//司机的信号 
HANDLE S2 = CreateSemaphore(NULL, 0, 1, "conductor_s");//乘务员的信号 
//!!!!!!!!!!!!!!你看,这里取了名字,在其他进程中可以直接用OpenSemaphore()来对名字进行索引!!!


int main()
{
	char lpPath[] = "conductor.exe";//用字符数组记录乘务员的进程的名字 
	STARTUPINFO si = {sizeof(si)}; //记录结构体有多大,必须要参数
	PROCESS_INFORMATION pi;    //进程id,进程句柄,线程id,线程句柄存在于这个结构体
	bool flag = CreateProcess(NULL,lpPath,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi); 
	while(!flag)
	flag = CreateProcess(NULL,lpPath,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi); //防止乘务员进程创建失败 
	
	
	//司机进程 
	while(true)
	{
		puts("司机正常行驶...");
		Sleep(1000);
		puts("司机到站停车...");
		ReleaseSemaphore(S2,1,NULL);
		WaitForSingleObject(S1,INFINITE);
		puts("司机离站开车...");
		Sleep(1000); 
	}
}
//乘务员进程代码 


#include<stdio.h> 
#include<windows.h>


HANDLE s1 = OpenSemaphore(SEMAPHORE_ALL_ACCESS, FALSE, "driver_s");//使用OpenSemaphore函数获得司机信号量 
HANDLE s2 = OpenSemaphore(SEMAPHORE_ALL_ACCESS, FALSE, "conductor_s");//获取乘务员信号量 
//你看,在这里就是通过信号量的名字获取的索引!!!!!!!


int main()
{

	while(true)
	{
		WaitForSingleObject(s2,INFINITE); 
		Sleep(1000);
		puts("乘务员工作:");
		Sleep(1000);
		puts("	开车门...");
		Sleep(1000);
		puts("	乘客上车...");
		Sleep(1000);
		puts("	售票...");
		Sleep(1000);
		puts("	关车门...");
		Sleep(1000);
		puts("乘务员工作结束..."); 
		ReleaseSemaphore(s1,1,NULL); 
	} 
	return 0; 
}

执行结果:
在这里插入图片描述

汽车司机售票员之间必须协同工作,一方面,只有售票员把车门关好了司机才能开车,因此,售票员关好车门应通知司机开车。另一方面,只有当司机已经停 下,售票员才能开门上下客,故司机停车后应通知售票员。假定某辆公共汽车上有两名售票员与一名司机,汽车当前正在始发站停车上客,试设必要的信号灯及赋初值,写出他们的同步过程 分析: 司机停车,通知售票员开门,售票员关门,通知司机开车 使用到的函数和信号量 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 );
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值