- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
考虑下一段代码。
#include <iostream>
#include <vector>
#include <map>
using namespace std;
map<pthread_t,vector<int>> map_vec;
vector<pair<pthread_t ,int>> how_much_and_where;
pthread_cond_t CV = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void* writer(void* args)
{
while(*some condition*)
{
int howMuchPush = (rand() % 5) + 1;
for (int i = 0; i < howMuchPush; ++i)
{
// WRITE
map_vec[pthread_self()].push_back(rand() % 10);
}
how_much_and_where.push_back(make_pair(pthread_self(), howMuchPush));
// Wake up the reader - there's something to read.
pthread_cond_signal(&CV);
}
cout << "writer thread: " << pthread_self() << endl;
return nullptr;
}
void* reader(void* args) {
pair<pthread_t, int> to_do;
pthread_cond_wait(&CV, &mutex);
while(*what condition??*)
{
to_do = how_much_and_where.front();
how_much_and_where.erase(how_much_and_where.begin());
// READ
cout << to_do.first << " wrote " << endl;
for (int i = 0; i < to_do.second; i++)
{
cout << map_vec[to_do.first][i] << endl;
}
// Done reading. Go to sleep.
pthread_cond_wait(&CV, &mutex);
}
return nullptr;
}
//----------------------------------------------------------------------------//
int main()
{
pthread_t threads[4];
// Writers
pthread_create(&threads[0], nullptr, writer, nullptr);
pthread_create(&threads[1], nullptr, writer, nullptr);
pthread_create(&threads[2], nullptr, writer, nullptr);
// reader
pthread_create(&threads[4], nullptr, reader, nullptr);
pthread_join(threads[0], nullptr);
pthread_join(threads[1], nullptr);
pthread_join(threads[2], nullptr);
pthread_join(threads[3], nullptr);
return 0;
}
map_vec
和how_much_and_where
。但在这种情况下,我不知道-map_vec
之前锁定push_back
?还是在for循环之前锁定它-但是不将其推送到队列是浪费且漫长的操作,这可能会导致读者要等待太多吗?)/how_much_and_where
是how_much_and_where
。 最佳答案
为简化起见,我们应该将通用/可重复使用的生产者-消费者队列(或我通常称之为“阻塞队列”)的实现与实际生产者和消费者(非通用)的实现分离开来。/可重用-它们特定于您的程序)。从设计的角度来看,这将使代码更加清晰和易于管理。
1.实现通用(可重用)阻塞队列
首先,您应该实现一个“阻塞队列”,该队列可以管理多个生产者和一个消费者。该阻塞队列将包含处理多线程/同步的代码,并且使用者线程可以使用它来接收来自多个生产者线程的项目。可以使用许多不同的方式(不仅是互斥锁+ cond组合)来实现这种阻塞队列,这取决于您是否拥有1个或多个消费者和1个或多个生产者(有时可以引入不同种类的[特定于平台的]优化)当您只有1个消费者或1个生产者时)。如果需要,最简单的使用互斥锁+条件对的队列实现可自动处理多个生产者和多个消费者。
队列只有一个内部容器(可以是非线程安全的std::queue,vector或list),用于容纳项以及相关联的互斥体+偶数对,可以保护该容器免于同时访问多个线程。队列必须提供两个操作:
produce(item)
:将一项放入队列并立即返回。伪代码如下所示:wait_and_get()
:如果队列中至少有一项,则它将删除最旧的一项并立即返回,否则它会等待有人通过produce(item)
操作将一项放入队列。pthread_cond_wait
)produce(item)
),然后退出。如果项目的生产不占用大量计算或不需要等待大量的IO操作,那么在示例程序中,这将很快完成。为了模拟线程在其中进行繁重工作的真实世界场景,您可以执行以下操作:在每个生产者线程上,您仅将X个(说5个)数量的项目放入队列,但是在每个项目之间您等待了随机的秒数在1到3秒之间。请注意,一段时间后,生产者线程会在完成工作时自行退出。
wait_and_get()
从队列中获取下一个项目,并以某种方式对其进行处理。如果它是一个特殊的项目,它表示处理结束,那么它将跳出无限循环,而不是处理该项目。伪代码:
wait_and_get()
)pthread_join()
编码)。produce(item)
操作。但是,队列中可能仍然有未处理的项目,并且消费者仍可以对这些项目进行处理。 wait_and_get()
向队列询问下一个商品-由于等待下一个永远不会到达的商品,这可能导致死锁。为了在主线程上提供帮助,我们将最后一个特殊项目放在队列中,该队列向使用者发出信号,表明处理结束。请记住,我们的消费者实现包含对此特殊项目的检查,以找出何时完成处理。重要的是,只有在生产者完成之后(加入他们之后),才必须将这个特殊项放到主线程上的队列中!pthread_join()
在主线程上等待。 NULL
作业指针。在您的情况下,您将必须找出可以在队列中使用的哪种特殊值,以表示对消费者的处理结束。 pthread_cond_wait
文档说,此功能可以在没有实际信号的情况下唤醒(尽管我从未见过此功能的虚假唤醒引起的单个错误)。为此,应将代码中的if container is empty then pthread_cond_wait
部分替换为while the container is empty pthread_cond_wait
,但同样,这种虚假的唤醒可能只是一个懒散的怪物,仅在某些具有线程原语的特定linux实现的体系结构中才存在,因此您的代码可能会在没有桌面线程的台式机上工作关心这个问题。 关于c++ - 具有pthread和锁且无提升的单读者多作者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36824992/
我无法理解为什么第一个读者-作者问题会导致写进程饿死,即:代码如何为读者进程提供优先级?当其中一个读取进程执行 signal(wrt) 时,写入进程是否应该无法获得锁定?是信号量列表的结构(正如我所看
我正在使用R处理人口普查数据,该数据使用了很长的数字GEOID来标识地理位置。我面临的问题是,当使用write_csv(来自readr包)写出处理后的数据时,正在以科学计数法编写这些GEOID。有办法
我为 Java 中的读写器问题开发了一个解决方案(有关此的一些信息 http://lass.cs.umass.edu/~shenoy/courses/fall08/lectures/Lec11.pdf
以下代码是Java中的Passing the Baton程序的一部分: 主要 P1(作家) P2(作家) P3(阅读器) P4(阅读器) 主要(); package ReadersPreference
我正在使用 ReaderWriterLockSlim保护一些操作。我想偏爱读者而不是作者,这样当读者长时间持有锁并且作者试图获取写锁时,进一步的读者不会被作者的尝试阻塞(如果作者在 lock.Ente
我觉得这可能是一种非常普遍和常见的情况,存在众所周知的无锁解决方案。 简而言之,我希望有像读者/作者锁这样的方法,但这不需要读者获取锁,因此可以获得更好的平均性能。 相反,读者需要一些原子操作(128
我遇到了读者-作者问题。我想写出作家喜欢使用互斥锁的解决方案。到目前为止我已经写了这个 #include #include #include #include #include #inclu
这个程序读取“电子邮件”(实际上只是一个像电子邮件一样结构的 .txt 文件)并用它做各种事情(在 map 中存储数据并对其进行操作)。 但是,我在根据主题搜索输出电子邮件的“消息”时遇到了一个不寻常
我正在从 UIWebView 切换到 WKWebView,不知道如何设置我的配置以使用 Reader. 有没有人可以帮助我? viewDidLoad: WKWebViewConfiguration *
我正在练习 Visual Basic 编程我在 Visual Basic 中有两种形式。第一个表单有一个命令按钮,将显示第二个表单的输入数据第二种形式有一个文本框,我需要在其中输入数据并保存它。 我在
我想寻求有关此任务的帮助。 我的任务是用 C 编写一个简单的程序来模拟读写器问题。程序要求是: 程序启动后,会要求用户输入作者和读者的输入次数。 程序会不断通知用户线程的状态。 程序结束后,小统计(每
我有一个用 C 语言模拟读者-作者问题的简单程序。要求用户输入作者数和读者数。然后创建随机数的编写器 - 线程和读取器 - 线程。项目的写入由全局变量 itemsCount 模拟 - 它代表新插入项目
我有一个“静态 64 位整数变量”,它仅由一个线程更新。所有其他线程仅从中读取。 出于安全原因,我是否应该使用原子操作(例如“__sync_add_and_fetch”)来保护这个变量? 还是可以直接
我是一名优秀的程序员,十分优秀!