Глобальные переменные в блоке CGO - утечка памяти и безопасность потоков в GO - PullRequest
0 голосов
/ 27 мая 2020

Я пытаюсь выяснить, существует ли проблема безопасности потоков и / или утечки памяти, связанная с глобальными переменными, объявленными в блоке CGO. Вот какой-то псевдокод:

/*    
char* globalchar;
int globalnum;

void init() {
 globalchar = "do something";
}

int process() {
  if (globalchar==NULL) {
    init();
  }
  globalnum=0;
  while (condition test) {
    dosomething_that_takes_time();
    globalnum++
  }
  return globalnum;
}
*/
import "C"
func goproc() {
  val := int(C.process())
}

gopro c () вызывается в нескольких потоках.

Вопрос 1. Является ли globalnum потокобезопасным? Могут ли им управлять одновременно разные потоки?

Вопрос 2. Есть ли какие-либо возможные проблемы, связанные с выполнением init () в этом шаблоне только один раз? Когда в Java используется одноэлементный шаблон, мы «синхронизируем» метод init (), чтобы убедиться, что только один человек может запустить его одновременно.

Вопрос 3. Будут ли globalnum и globalchar автоматически собирать мусор? Я заметил много: defer C .free (unsafe.Pointer (somecpointer)). Нужно ли это делать с глобальными переменными, объявленными в блоке CGO?

Любые советы были бы полезны. Спасибо!

1 Ответ

2 голосов
/ 27 мая 2020

По вопросу 1: нет, это небезопасно. Используйте мьютекс где-нибудь - в самом коде C, скорее всего, с мьютексом в стиле POSIX - для синхронизации доступа к совместно используемым данным. Или, если хотите, используйте целое число C11 atomi c.

По вопросу 2: это тоже небезопасно. Используйте где-нибудь мьютекс.

По вопросу 3: глобальные переменные C не нуждаются в G C. Один не является указателем, а другой - указателем, который указывает на stati c -duration C память, содержащую C строковый литерал do something (в любом случае после init).

...