我的程序有一个shared queue
,并且大致分为两部分:
一个用于将class实例推request
送到queue
,另一个用于访问中的多个request
对象queue
并处理这些对象。request
是带有string req
字段的非常简单的类(仅用于测试)。
我正在研究第二部分,为此,我想保留一个scheduling thread
和多个(在我的示例中为两个)executing threads
。
我想有一个单独的原因scheduling thread
是数量减少lock
和unlock
操作访问的queue
多个executing threads
。
我正在使用pthread库,并且我的调度和执行函数如下所示:
void * sched(void* elem) {
queue<request> *qr = static_cast<queue<request>*>(elem);
pthread_t pt1, pt2;
if(pthread_mutex_lock(&mut) == 0) {
if(!qr->empty()) {
int result1 = pthread_create(&pt1, NULL, execQueue, &(qr->front()));
if (result1 != 0) cout << "error sched1" << endl;
qr->pop();
}
if(!qr->empty()) {
int result2 = pthread_create(&pt2, NULL, execQueue, &(qr->front()));
if (result2 != 0) cout << "error sched2" << endl;
qr->pop();
}
pthread_join(pt1, NULL);
pthread_join(pt2, NULL);
pthread_mutex_unlock(&mut);
}
return 0;
}
void * execQueue(void* elem) {
request *r = static_cast<request*>(elem);
cout << "req is: " << r->req << endl; // req is a string field
return 0;
}
简单来说,每个execQueue
线程都有一个要执行的线程,并且仅输出通过void* elem
参数传递给它的请求。
sched
main()
通过一个线程在中调用(如果您想知道如何调用,则main()
如下所示)
pthread_t schedpt;
int schresult = pthread_create(&schedpt, NULL, sched, &q);
if (schresult != 0) cout << "error sch" << endl;
pthread_join(schedpt, NULL);
和sched
函数本身创建多个(两个在这里)executing threads
和pop
小号request
从S queue
,并执行request
调用小号execQueue
在多线程(在pthread_create,然后ptrhead_join)。
问题是程序的行为异常。
当我检查队列中的大小和元素而不创建线程并在多个线程上调用它们时,它们正是我所期望的。
但是,当我运行带有多个线程的程序时,它会打印出来
队列中有1个项目。队列中有2个项目。要求是:要求是:第一! (x' j| 1? rj|p rj|1 第一! 'j|! ' j| 'j|P ( ( (1 ? i|p i|
最后一行不断变化。
所需的输出是
队列中有1个项目。队列中有2个项目。要求是:第一要求是:第一
我猜想我是execQueue
在多个线程上调用的方式,还是我pop()
错了的方式,但是我无法弄清楚问题,也找不到任何参考资料来正确使用。
请帮我。我是初学者,请耐心等待pthread的笨拙用法。
您的队列包含对象,而不是对象的指针。您可以operator &()
按原样通过寻址队列的最前面的对象,但是一旦弹出队列,该对象就消失了,该地址不再有效。当然,sched
这无关紧要,但是execQueue
您发送该地址的功能确实可以。
您的代码最直接的解决方法是:
更改此:
pthread_create(&pt1, NULL, execQueue, &(qr->front()));
对此:
// send a dynamic *copy* of the front queue node to the thread
pthread_create(&pt1, NULL, execQueue, new request(qr->front()));
并且您的线程proc应该更改为:
void * execQueue(void* elem)
{
request *r = static_cast<request*>(elem);
cout << "req is: " << r->req << endl; // req is a string field
delete r;
return nullptr;
}
也就是说,我可以想到更好的方法,但这应该解决您的紧迫问题,假设您的request
对象类是可复制构造的,并且如果它具有动态成员,则遵循三个规则。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句