Реализуйте ThreadPool, который может вызывать функции с несколькими аргументами в C ++ - PullRequest
4 голосов
/ 16 ноября 2011

Я написал реализацию ThreadPool на C #, и теперь я хотел бы перенести ее в стандартный C ++ (если возможно, с boost). Исходная версия C # может вызывать функции с несколькими аргументами, используя делегаты, а код выглядит примерно так:

    public static void RunOrBlock(Function function)
    {
        WorkItem workItem = new WorkItemNoArguments(function);
        RunOrBlock(workItem);
    }

    public static void RunOrBlock<T1>(Function<T1> function, T1 t1)
    {
        WorkItem workItem = new WorkItem<T1>(function, t1);
        RunOrBlock(workItem);
    }

Здесь «функция» определяется с помощью делегата:

public delegate void Function();
public delegate void Function<in T1>(T1 t1);

И WorkItem можно определить аналогично:

public abstract class WorkItem
{
    protected int threadIndex;

    public int ThreadIndex
    {
        get { return threadIndex; }
        set { threadIndex = value; }
    }

    public abstract void Run();
}

public class WorkItem<T1> : WorkItem
{
    private readonly Function<T1> _function;
    private readonly T1 _t1;

    public WorkItem(Function<T1> function, T1 t1)
    {
        _function = function;
        _t1 = t1;
    }

    public override void Run()
    {
        _function(_t1);
    }
}

Я прочитал некоторые материалы для pThread и знаю, что можно объявить эти аргументы в структуре и затем привести их к (void *). Однако, поскольку большинство моих функций уже реализовано, использование этого способа будет крайне неудобным.

Мой вопрос: поскольку в C ++ нет поддержки делегатов, каков удобный и удобный способ реализации пула потоков, который поддерживает вызов функций с несколькими аргументами?

Ответы [ 2 ]

4 голосов
/ 16 ноября 2011

Вы можете использовать boost's bind для генерации нулевых функций. Это было бы несколько многословно, но вместо звонка RunOrBlock(f, a1, a2, ...) вы могли бы сделать RunOrBlock(bind(f, a1, a2, ...)).

2 голосов
/ 16 ноября 2011

Уверен, что единственный "хороший" способ сделать это - использовать вариабельные шаблоны C ++ 11.Например:

template <typename RetType, typename Function, typename... Args>
RetType CallFunc(Func f, Args... args)
{
    return f(args...);
}

В противном случае вам придется написать несколько версий для 1 аргумента, 2 аргументов, 3 аргументов и т. Д. Или использовать какую-то черную магию, которая будет небезопасной или не переносимой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...