如何解决如果有 1 个生产者和许多消费者,如何解决生产者消费者问题 缓冲区大小为 1
如果有 1 个提供文件名的生产者和两个使用文件名的消费者,如何解决生产者消费者问题。
扭曲的是添加文件名的缓冲区的大小为 1,这意味着我们不能有 2 个副本供每个消费者使用。
对于同一个文件,两个消费者都有不同的运行逻辑。
我没有包含退出条件逻辑,但它会在文件名等于 EXIT 时终止线程。
数据在生产者/消费者之间通过指针共享。
共享数据:
char* filenameBuffer;
pthread_mutex_t filenameMutex;
pthread_cond_t canProduceFilename;
pthread_cond_t canConsumeFilename;
目前我让制作人做这样的事情。
父/生产者线程 - 将循环直到我想退出。
while(!exit)
{
pthread_mutex_lock(filenameMutex);
//Check if the string is empty.
if(filenameBuffer != '\0')
{
p_thread_cond_wait(canProduceFilename,filenameMutex);
}
scanf("%s",filenameBuffer);
pthread_cond_signal(canConsumeFilename);
pthread_mutex_unlock(filenameMutex);
}
儿童/消费者话题 - 我们有 2 个。
while (!exit)
{
pthread_mutex_lock(filenameMutex);
//Loop until a string is produced.
while (filenameBuffer == '\0')
{
p_thread_cond_wait(canConsumeFilename,filenameMutex);
}
//Do something with filename,not relevant for solution.
pthread_mutex_unlock(filenameMutex);
}
那么我如何能够在不控制每个消费者线程的顺序的情况下使用消费者内部的文件名。我不想强制执行哪个消费者可以先运行的顺序,因为这会破坏多线程的意义。
如果有任何澄清或需要更多信息,我会留下来。
非常感谢任何讨论或指导。
亲切的问候。
解决方法
我编造了一个使用 Ada 编程语言如何工作的示例。由于文件名的处理对这个问题并不重要,我创建了两个消费者,它们处理他们收到的任何字符串,直到字符串等于“退出”。
此示例创建一个受保护的对象,其中包含一个元素缓冲区和一个计数器。它还实现了两个条目,写入和读取。写条目仅在计数器等于 0 时执行。读条目仅在计数器大于 0 时执行。
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
procedure Main is
type Count_Type is range 0..2;
protected buffer is
entry write(S : in Unbounded_String);
entry read(S : out Unbounded_String);
private
Counter : Count_Type := 0;
Element : Unbounded_String;
end Buffer;
protected body buffer is
entry write (S : in Unbounded_String) when Counter = 0 is
begin
Element := S;
Counter := 2;
end write;
entry read (S : out Unbounded_String) when Counter > 0 is
begin
S := Element;
Counter := Counter - 1;
end read;
end buffer;
task producer;
task body producer is
Msg : Unbounded_String := To_Unbounded_String("Message");
begin
for I in 0..9 loop
Msg := Msg & Integer'Image(I);
Buffer.write(Msg);
end loop;
Msg := To_Unbounded_String("Exit");
Buffer.Write(Msg);
end producer;
task consumer_1;
task body consumer_1 is
Msg : Unbounded_String;
begin
loop
Buffer.Read(Msg);
exit when To_String(Msg) = "Exit";
Put_Line("Con1 -> " & To_String(Msg));
end loop;
end consumer_1;
task consumer_2;
task body consumer_2 is
Msg : Unbounded_String;
begin
loop
Buffer.Read(Msg);
exit when To_String(Msg) = "Exit";
Put_Line("Con2 -> " & To_String(Msg));
end loop;
end consumer_2;
begin
null;
end Main;
程序的输出为:
Con1 -> Message 0
Con2 -> Message 0
Con1 -> Message 0 1
Con2 -> Message 0 1
Con1 -> Message 0 1 2
Con2 -> Message 0 1 2
Con2 -> Message 0 1 2 3
Con2 -> Message 0 1 2 3 4
Con1 -> Message 0 1 2 3
Con2 -> Message 0 1 2 3 4
Con1 -> Message 0 1 2 3 4 5
Con2 -> Message 0 1 2 3 4 5
Con1 -> Message 0 1 2 3 4 5 6
Con2 -> Message 0 1 2 3 4 5 6
Con1 -> Message 0 1 2 3 4 5 6 7
Con2 -> Message 0 1 2 3 4 5 6 7
Con1 -> Message 0 1 2 3 4 5 6 7 8
Con2 -> Message 0 1 2 3 4 5 6 7 8
Con1 -> Message 0 1 2 3 4 5 6 7 8 9
Con2 -> Message 0 1 2 3 4 5 6 7 8 9
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。