我有两个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
问题是如何同时编译和运行它们?
这是实际的任务。(我知道可以使用一个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