此代码的作用:
执行完成的几个命令(如果(当前秒= =几秒)停止)。 CommandProcessor(仿函数)运行此命令。这个类的指针我试着抛出pthread_create。
问题:
可以使用类对象作为可调用的吗?
command.h
#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);
}
commandprocessor.h
#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;
}
答案 0 :(得分:4)
免责声明:这是你在C ++中不应该做的事情,因为它包含了void*
。由于与C API的交互,因此需要在此处使用它。如果可以,请使用C ++ 11中的std::thread或boost::thread,如果您使用的是较旧的编译器。
回答你的问题:是的,一旦你为它实现operator()
,就可以将一个类对象作为一个可调用对象(作为一个&#34;函数&#34;)。您已经这样做了,但问题是实现C ++与Pthreads的C API之间的接口所需的额外代码。
您获取&#34; processor
的主要原因不能用作功能&#34;这里的错误是因为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
的相应调用提供了值pthread_create
。
但是,由于更重要的原因,您无法将指针传递给CommandProcessor::operator()()
到pthread_create
:它是一个成员函数。需要使用对象调用所有非static
类成员函数,以便它们可以引用其体内的this
。
问题的解决方案是创建一个与pthread_create
所需原型匹配的静态函数,并将指针传递给CommandProcessor
作为arg
pthread_create
}。看看这个:
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
创建的线程内执行,使用与CommandProcessor
中相同的main()
对象。
请记住,从许多并行线程中访问相同的数据将导致数据争用。使用互斥锁,信号量或条件变量来保护数据不受并行访问的影响。