生产者消费者问题
- 1实验目的
- 2实验内容
- 3实验环境
-
- 3.1Windows
- 3.2Linux虚拟机
- 4程序设计和实现
-
- 4.1Windows实现
-
- 4.1.1函数解释
- 4.1.2程序代码
- 4.1.3运行结果
- 4.2Linux实现
-
- 4.2.1函数解释
- 4.2.2程序代码
- 4.2.3运行结果
Make C or C++ programs to illustrate the Producer and Consumer synchronization problem. You will have to create several processes to simulate the producers and consumers. Use shared memory to implement the shared buffer among producers and consumers. Use semaphore to synchronize the processes. Here are some constraints for the problem.
? A shared buffer with 3 slots, initially are all empty.
? Two producers
– Randomly wait for a period of time and put product into the buffer.
– Wait if the buffer slots are all full
– Repeat 6 times.
? Three consumers
– Randomly wait for a period of time and fetch a product from the buffer.
– Wait if the buffer slots are all empty.
– Repeat 4 times.
1实验目的
制作C或C++程序来说明生产者和消费者同步问题。您必须创建几个流程来模拟生产者和消费者。使用共享内存实现生产者和消费者之间的共享缓冲区。使用信 量来同步进程。
2实验内容
?一个有3个插槽的共享缓冲区,最初都是空的。
?两个生产商
–随机等待一段时间,将产品放入缓冲区。
–如果缓冲槽已满,请等待
–重复6次。
?三个消费者
–随机等待一段时间,然后从缓冲区提取产品。
–如果缓冲槽全部为空,请等待。
–重复4次。
笔记:
?显示缓冲区的状态以及产品放入或移出缓冲区的时间。
?使用过程(非线程)模拟消费者和生产者。
?使用fork()和CreateProcess()等系统调用创建新流程。在Linux中使用系统调用,如shmget()创建共享内存,使用semget()创建信 量。
?在windows中,共享内存实现为内存映射文件,您可以使用函数CreateFileMapping创建共享内存。你可以找到更多关于https://docs.microsoft.com/en-us/windows/win32/memory/creating-named-shared-memoryedirectedfrom=MSDN.
?您可以使用CreateSemaphore和CreateSmutex在Windows中创建信 量和互斥锁。
?实施Windows版本和Linux版本。
3实验环境
3.1Windows
操作系统:Windows 10
处理器:AMD 3800X
3.2Linux虚拟机
操作系统:Ubantu 20.04.3
虚拟机软件:VMware Workstation 15
虚拟处理器:1个6核
4程序设计和实现
4.1Windows实现
4.1.1函数解释
4.1.1.1 CreateFileMapping()是用于创建一个文件映射内核对象的函数
HANDLE handleFileMapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(sharememory), SHM_NAME);
参数hFile使用INVALID_HANDLE_VALUE,表示在页面文件中创建一个可共享的文件映射,在本实验中用于作为共享内存
参数flProtect使用PAGE_READWRITE,表示以可读、写的方式打开映射
参数dwMaximumSizeLow使用sizeof(shm),该数据为文件映射最大长度的低32位,表示该文件大小只有在4.1.1定义的数据结构sharememory一样大。
参数lpName使用SHM_NAME该值为宏定义,表示共享内存区名字
4.1.1.2 MapViewOfFile()是用于将一个文件映射对象映射到当前程序地址空间的函数
LPVOID WINAPI MapViewOfFile(
_In_HANDLE hFileMappingObject,
_In_DWORD dwDesiredAccess,
_In_DWORD dwFileOffsetHigh,
_In_DWORD dwFileOffsetLow,
_In_SIZE_T dwNumberOfBytesToMap
);
LPVOID shareMemoryAddress = MapViewOfFile(handleFileMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0);
参数hFileMappingObject使用CreateFileMapping的返回句柄,表示将创建的对应的文件映射对象映射到程序地址空间
参数dwDesiredAccess使用FILE_MAP_ALL_ACCESS,表示可以使用文件所有权限,是与创建文件映射对象相对应的权限
4.1.1.3 UnmapViewOfFile()是用于停止当前程序的一个内存映射的函数
BOOL WINAPI UnmapViewOfFile(
_In_LPCVOID lpBaseAddress
);
参数pFile是函数MapViewOfFile()函数返回的文件映射对象句柄
该函数用于解除当前进程地址空间对一个文件映射对象的映射
4.1.1.4 OpenFileMapping()是用于打开一个已经存在的文件映射对象的函数,返回相应打开的句柄
HANDLE OpenFileMapping(
_In_DWORD dwDesiredAccess,
_In_BOOL bInheritHandle,
_In_LPCSTR lpName
);
参数dwDesireAccess使用FILE_MAP_ALL_ACCESS,表示打开该映射对象时具有全部权限,和创建文件对象对应
参数bInheritHandle使用FALSE,表示由该进程启动的新进程不允许继承该句柄,防止错误发生
参数lpName使用SHM_NAME,表示打开创建的名为SHM_NAME的文件映射对象
4.1.1.5 CreateSemaphore()是用于创建一个信 量的函数,返回对应信 量的句柄
HANDLE CreateSemaphore(
LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
LONG lInitialCount,
LONG lMaximumCount,
LPCTSTR lpName
);
参数lInitialCount和lMaximumCount分别表示该信 量初始值和最大可以到达的值,实验中设置如下:
sem_empty 初始值:BUFFER_LEN 最大值:BUFFER_LEN
sem_full 初始值:0 最大值:BUFFER_LEN
sem_mutex 初始值:1 最大值:1
参数lpName是信 量的名字
4.1.1.6 CloseHandle()是用于关闭现有已打开句柄的函数
BOOL CloseHandle(
HANDLE hObject
);
参数hFileMapping是函数OpenFileMapping()的返回值,是一个已经打开的文件映射对象句柄
该函数解除了对该进程对文件映射对象句柄的使用,防止内核泄漏
4.1.2程序代码
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!