Передача новых данных в асинхронную многопоточную функцию, которая все еще может использовать старые данные - PullRequest
0 голосов
/ 25 февраля 2011

У меня возникла проблема, связанная с C / C ++: Предположим, у меня есть класс

class Demo
{
   int constant;
   public:
    void setConstant(int value)
    {
        constant=value;
    }
    void submitTask()
    {
       // need to make a call to C-based runtime system to submit a 
       // task which will be   executed "asynchronously"
       submitTask((void *)&constant);
    }
};

// runtime system will call this method when task will be executed
void func(void *arg)
{
    int constant= *((int *)arg);
    // Read this constant value but don't modify here....
}

Теперь в моем приложении я делаю что-то вроде этого:

int main()
{
  ...
  Demo objDemo;
  for(...)
  {
     objDemo.setConstant(<somevalue>);
     objDemo.submitTask();
  }
  ...
}

Теперь, надеюсь, вы видите проблему, поскольку задачи должны прочитать значение, установленное непосредственно перед асинхронным вызовом. Поскольку вызовы задачи асинхронны, задача может прочитать неправильное значение и иногда приводит к неожиданному поведению.

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

Заранее спасибо.

1 Ответ

5 голосов
/ 25 февраля 2011

Если вы не хотите ждать завершения кода C, прежде чем делать следующий вызов, вы не можете использовать одну и ту же ячейку памяти снова и снова. Вместо этого создайте массив и затем передайте эти местоположения. Для этого кода я предполагаю, что число циклов for будет равно n. Это не должно быть известно, пока не настанет время для цикла for.

int* values = new int[n];
for(int i=0;i<n;i++) {
    values[i] = <somevalue>;
    submitTask((void*)&values[i]);
}

В какой-то момент, когда вы уверены, что все сделано, позвоните

delete[] values;

Или, вместо этого, вместо массива целых, создайте массив демонстрационных объектов.

Demo demo[] = new Demo[n];
for(int i=0;i<n;i++) {
    demo[i].setConstant(<somevalue>);
    demo[i].submitTask();
} 

Но первое имеет для меня больше смысла, поскольку демо-объект, похоже, не делает ничего стоящего. Но, возможно, вы не указали методы и элементы, не относящиеся к данному вопросу, чтобы можно было выбрать, какой вариант лучше. Несмотря на это, дело в том, что вам нужны отдельные области памяти для отдельных значений, если вы не знаете, когда они будут использоваться, и не хотите ждать.

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