繁体   English   中英

在pthread_create中使用仿函数

[英]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用作功能”错误的主要原因是processorCommandProcessor* ,因此需要取消引用。 但是,即使执行(*processor)()也无济于事,因为pthread_create的定义如下:

int pthread_create(phread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);

这意味着要执行的函数必须返回void*并采用void* 该文档还指出, start_routinearg最初将arg的值arg赋予了对pthread_create的相应调用。

但是,由于更重要的原因,您不能将指向CommandProcessor::operator()()的指针传递给pthread_create :它是成员函数。 所有非static类的成员函数需要一个对象被调用,以便他们可以参考this自己的身体里面。

解决您的问题的方法是制作一个与pthread_create所需原型相匹配的静态函数,并将指针作为pthread_createarg传递给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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM