同时运行两个共享内存的C程序,如何实现?

3
我有两个c文件:producer.c和consumer.c。Consumer在内存中创建一个共享缓冲区,并等待生产者将项目放入缓冲区以供消费。生产者将共享内存附加到其内存映射中,然后开始将项目放入缓冲区。
问题是如何同时编译和运行它们?
这是实际的任务。(我知道可以使用一个c文件使用线程来完成,但这不是我被要求做的。)
在这个部分,您将开发一个使用共享内存进行进程通信的生产者消费者应用程序(POSIX共享内存,而不是System V共享内存)。将有N个生产者和N个消费者。N可以是1,2或3。
您将开发一个生产者程序(producer.c)和一个消费者程序(consumer.c)。当启动时,生产者程序将创建N个子进程,这些子进程将充当N个生产者(即每个子进程将是生产者进程)。
类似地,当启动时,消费者程序将创建N个子进程,其中每个子进程将充当消费者进程。您将认为消费者是0、1、2,具体取决于N。例如,如果N为2,则将有两个消费者,0和1。
消费者程序将首先运行。运行时,消费者程序将首先创建一个大小为4KB的共享内存。这个共享内存将是您拥有一个共享的单个缓冲区的地方。生产者和消费者都可以访问该缓冲区。缓冲区大小为100。它最多可以容纳100个项目(整数)。在共享内存中,您可以拥有一些其他共享变量,这些变量您认为是必要的。消费者程序还将创建一个或多个信号量(您决定要使用多少个)。
然后,它将使用fork()系统调用创建N个子进程(N个消费者)。消费者程序的主进程(父进程)在创建子进程后不应终止。它应该等待所有子进程(即消费者)完成任务并终止。当所有子进程终止时,它将从系统中删除(删除)共享内存。它还将删除(删除)信号量。然后它也可以终止。
每个生产者都将读取一个正整数的输入文件(每行一个整数),并将整数通过由消费者程序创建的共享内存中的共享缓冲区传递。
每个消费者都将从共享缓冲区中读取整数,并将接收到的整数z写入与消费者相关联的输出文件,如果z mod N等于消费者的ID,则为1.例如,如果N为3,如果消费者的ID为2且消费者已收到一个整数7,则它将不做任何处理(忽略),但是如果它收到8,则将整数写入其输出文件。输出文件将在一行中包含一个整数。在生产者和消费者访问共享缓冲区时,它们应该使用信号量进行同步。此外,如果缓冲区已满,则生产者应该睡眠,如果没有可消费的物品,则消费者应该睡眠。我们不应该有繁忙的等待。您将使用POSIX信号量(命名信号量)。消费者程序将如下调用:
消费者N…
在这里,N是要创建的消费者进程的数量。该参数的值必须与生产者程序的相应参数相同。在此处,“…”是将由ID为X的消费者使用的输出文件的名称。输入的输出文件名数将等于N。是我们可以用来标识共享内存的名称。是我们可以用来标识信号量的名称(它可以是可用于许多信号量名称的前缀)。在调用生产者时必须使用相同的名称。生产者程序将命名为producer,并使用以下参数调用:
生产者N…
在这里,N是制片人的数量。“…”是生产者X的一个输入文件的名称。输入文件是存储整数的文本文件。我们输入的输入文件名数将等于N。文件中可以有一个或多个整数。输入文件可能非常巨大(数十亿个整数)。是我们可以用来标识共享内存的名称。是我们可以用来标识信号量的名称。
程序的示例调用可能如下所示。
消费者3 out0.txt out1.txt out2.txt mysmem mysemaphores 生产者3 in0.txt in1.txt in2.txt mysmem mysemaphore

你所说的“together”具体是什么意思? - undefined
12
你需要一款新式的多任务操作系统。Unix系统在大型计算机上已经有这个功能一段时间了,而我听说你可以在这种时髦的新型Amiga电脑上得到它。 - undefined
2
询问共享内存与操作系统无关?你在开玩笑吗?看起来你对 Stack Overflow 还不熟悉,但是这里的问题需要准确地提出,告诉我们你拥有什么和你想要实现什么。我们不在这里为你做“作业”。你有没有在谷歌上搜索过“生产者消费者共享内存”? - undefined
你可能需要稍微改一下问题的措辞。如果你能够编译出两个不同的二进制文件,并且你的问题与同步有关,请在问题中明确说明。这样可以让遇到相同问题的人通过搜索引擎找到这个问题。 - undefined
我知道自己在做什么并且明确自己在问什么。我已经在一个单独的文件中使用线程实现了这个任务。现在我正在尝试使用两个不同的C文件来实现它。 - undefined
显示剩余2条评论
4个回答

5
问题是如何同步共享一些内存的两个进程。您可以使用Posix信号量,但还有许多其他方法可以实现这一点。

我已经实现了信号量。问题是如何编译和运行producer.c和consumer.c。例如,consumer.c创建缓冲区并等待producer将项目放入缓冲区。 - undefined

1

你不能简单地共享内存。你必须请求操作系统为你提供可以与另一个进程共享的内存访问权限。要使用的API取决于你的操作系统。此外,即使在像Linux这样的操作系统上,也有多种不同的方法来实现这一点,每种方法都有其优缺点和限制。这里有另一个问题,其中讨论了一些替代方案 Shmem vs tmpfs vs mmap


1
只需在每个模块中添加一个 main()。分别编译它们以生成两个不同的二进制文件并运行它们。

两个文件都有自己的主函数。然而,问题在于它们在有限的共享内存上工作,有时一个需要等待另一个,反之亦然。 - undefined
@user853005:Basile Starynkevitch的提议是一个可行的方案。 - undefined

0
我同意使用信号量和共享内存。在Linux环境下,我建议使用Posix信号量用于进程控制以及System V共享内存。当然也可以通过其他方式实现相同的功能,只不过我认为这些方法比较简单易懂。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接