[英]Using functor in pthread_create
该代码的作用:
几个执行完成的命令(如果(当前秒==几秒)停止)。 CommandProcessor(functor)运行此命令。 我尝试将此类的指针扔给pthread_create。
问题:
可以将类对象用作可调用对象吗?
命令
#ifndef COMMAND_H
#define COMMAND_H
#include <iostream>
#include "commandprocessor.h"
class CommandProcessor;
using namespace std;
class Command
{
static CommandProcessor *commandProcessor;
time_t stopSeconds;
public:
Command(int _stopSeconds);
static void setProcessor(CommandProcessor *_commandProcessor);
void execute();
};
#endif // COMMAND_H
command.cpp
#include "command.h"
CommandProcessor* Command::commandProcessor = NULL;
Command::Command(int _stopSeconds)
{
stopSeconds = _stopSeconds;
}
void Command::setProcessor(CommandProcessor *_commandProcessor)
{
commandProcessor = _commandProcessor;
}
void Command::execute()
{
time_t seconds;
time_t now = time(NULL);
seconds = localtime(&now)->tm_sec;
cout << seconds << endl;
if(seconds != stopSeconds)
commandProcessor->addCommand(this);
}
命令处理器
#ifndef COMMANDPROCESSOR_H
#define COMMANDPROCESSOR_H
#include <list>
#include "command.h"
using namespace std;
class Command;
class CommandProcessor
{
list< Command* > commandsList;
public:
void addCommand(Command *_command);
void operator()();
};
#endif // COMMANDPROCESSOR_H
commandprocessor.cpp
#include "commandprocessor.h"
void CommandProcessor::addCommand(Command *_command)
{
commandsList.push_back(_command);
}
void CommandProcessor::operator()()
{
while(commandsList.size() > 0)
{
Command *command = commandsList.front();
commandsList.pop_front();
command->execute();
}
}
main.cpp
#include <iostream>
#include <pthread.h>
#include "commandprocessor.h"
#define MAX_THREADS 2
using namespace std;
int main(int argc, char **args)
{
CommandProcessor *processor = new CommandProcessor();
Command::setProcessor(processor);
processor->addCommand(new Command(53));
processor->addCommand(new Command(24));
processor->addCommand(new Command(15));
pthread_t threads[MAX_THREADS];
for(int i=0; i < MAX_THREADS; i++)
{
pthread_create(&threads[i], NULL, processor(), NULL); // error: 'processor' cannot be used as a function
}
return 0;
}
免责声明:这是您实际上不应该在C ++中做的事情,因为它包括弄乱void*
。 由于与C API的交互,因此需要在此处使用它。 如果可以,请使用C ++ 11中的std :: thread ;如果使用的是较旧的编译器,请使用boost :: thread 。
要回答你的问题:是的,一旦为它实现了operator()
,就可以将一个类对象作为可调用的对象(作为“函数”)。 您已经做到了,但是问题是实现C ++和Pthreads的C API之间的接口所需的额外代码。
出现“无法将processor
用作功能”错误的主要原因是processor
是CommandProcessor*
,因此需要取消引用。 但是,即使执行(*processor)()
也无济于事,因为pthread_create
的定义如下:
int pthread_create(phread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
这意味着要执行的函数必须返回void*
并采用void*
。 该文档还指出, start_routine
的arg
最初将arg
的值arg
赋予了对pthread_create
的相应调用。
但是,由于更重要的原因,您不能将指向CommandProcessor::operator()()
的指针传递给pthread_create
:它是成员函数。 所有非static
类的成员函数需要一个对象被调用,以便他们可以参考this
自己的身体里面。
解决您的问题的方法是制作一个与pthread_create
所需原型相匹配的静态函数,并将指针作为pthread_create
的arg
传递给CommandProcessor
。 看看这个:
static void* processor_executor(void *arg)
{
CommandProcessor *processor = static_cast<CommandProcessor*>(arg);
(*processor)();
return NULL;
}
int main(int argc, char **argv)
{
/* ... */
for(int i=0; i < MAX_THREADS; i++)
{
pthread_create(&threads[i], NULL, processor_executor, static_cast<void*> (processor));
}
/* ... */
}
这样, operator()
在pthread_create
创建的线程内执行,使用与main()
相同的CommandProcessor
对象。
请记住,从许多并行线程中访问相同的数据将导致数据争用。 使用互斥量,信号量或条件变量来保护数据免受并行访问。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.