在pthread_create中使用functor

时间:2014-07-22 18:49:06

标签: c++ functor

此代码的作用:

执行完成的几个命令(如果(当前秒= =几秒)停止)。 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;
}

1 个答案:

答案 0 :(得分:4)

免责声明:这是你在C ++中不应该做的事情,因为它包含了void*。由于与C API的交互,因此需要在此处使用它。如果可以,请使用C ++ 11中的std::threadboost::thread,如果您使用的是较旧的编译器。

回答你的问题:是的,一旦你为它实现operator(),就可以将一个类对象作为一个可调用对象(作为一个&#34;函数&#34;)。您已经这样做了,但问题是实现C ++与Pthreads的C API之间的接口所需的额外代码。

您获取&#34; processor的主要原因不能用作功能&#34;这里的错误是因为processorCommandProcessor*,因此需要取消引用。但是,即使执行(*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()对象。

请记住,从许多并行线程中访问相同的数据将导致数据争用。使用互斥锁,信号量或条件变量来保护数据不受并行访问的影响。