2016-10-19 2 views
1

(Это следует Are static inline functions thread safe?)Являются ли функции указателями потоками безопасными?

Сценарий: Я написал большой кусок кода, работает на 2-х параллельных нитей, которые идентичны в плане кода и просто обрабатывать различные данные. Я вижу недетерминированные результаты. Если я отключу один из двух потоков, результаты станут детерминированными. Внутри этого кода я использую некоторые указатели на функции, и я хотел бы понять, могут ли они стать возможной причиной моей проблемы.

Функциональные указатели поточно-безопасные в C? С другой стороны, если у них нет статической переменной внутри, но только некоторые локальные переменные и входные параметры, будет ли одновременный вызов из 2 потоков вызвать непредсказуемое поведение?

Пример кода:

void foo(int param1, int* out); 
void bar(int param1, int* out); 

typedef void (*fooBarFuncP_t)(int, int*); 

static inline fooBarFuncP_t getFooBar(int selection) { 
    switch (selection) { 
     case 0: 
      return &foo; 
     case 1: 
     default: 
      return &bar; 
    } 
} 

void test(int selection, int x, int* y) { 
    (*getFooBar(selection))(x,y); 
} 

Где:

  • В их реализации, foo и bar имеют только локальные, не являющиеся статические переменные
  • y выделяется отдельно для 2-х потоков, вызывающей от испытания

Является ли это потокобезопасным? Если нет, то какие решения существуют для этой проблемы?

+0

Нет гонки данных здесь. – 2501

+0

Таким образом, между 'foo' и' bar' нет взаимодействия, не так ли? На первый взгляд я здесь не вижу никаких проблем. –

+0

@MichaelWalz Хорошая точка. 'foo' и' bar' используют некоторый буфер (это часть входных параметров). Но буферы распределяются отдельно для двух потоков, а 'foo' и' bar' не вызываются одновременно * в пределах одного потока *. (Я проверю дважды) – Antonio

ответ

1

Указатель на использование/использование функции не отличается от функции, связанной с безопасностью потока. В приведенном примере вы не указали проблемы с безопасностью потока (в соответствии с условиями, указанными вами).

Предполагая, что вы все еще есть проблемы, связанные с потокобезопасности некоторые предложения:

  • Проверьте, есть ли данные гонки в вашем коде.

  • Проверьте, есть ли какие-либо статические переменные, связанные с заголовками, библиотечными функциями, сторонними функциями и т. Д. (Я знаю, что вы сказали никому, но все же возможно, что вы пропустили некоторые).

  • Запустите свой код под Helgrind.

0

Нет никакой разницы между указателями функций и регулярными переменными с точки зрения безопасности потоков. Если переменная разделяется несколькими потоками и, по крайней мере, при записи потока в переменную, вам необходимо ее защитить.

Функция, вызываемая функцией, не имеет отношения к безопасности потока этой функции. Единственное, что имеет значение, это тот поток, который выполняет эту функцию. Если несколько потоков вызывают одну и ту же функцию, независимо от того, как они это делают, тогда эта функция должна быть потокобезопасной.

+0

Разве это не значит, что функция в соответствии с моим примером является потокобезопасной? (См. Также примечания под ним) – Antonio

+0

@ Антонио Функция «тест» ничего не делает с общими ресурсами, поэтому нет причин, по которым это было бы небезопасно. Является ли этот пример потокобезопасным или зависит не только от того, являются ли две вызываемые функции потокобезопасными. – Lundin

Смежные вопросы