где определяется безопасность потоков Файна? - PullRequest
1 голос
/ 14 января 2020

Меня привлекло Fyne (и, следовательно, Go) обещанием безопасности потоков. Но теперь, когда я стал лучше читать Go, я вижу вещи, которые заставляют поверить, что API в целом не является поточно-ориентированным и, возможно, никогда не предназначался для этого. Поэтому я пытаюсь определить, что означает «потокобезопасность» в Fyne.

Я специально смотрю на

func (l *Label) SetText(text string) {
    l.Text = text
    l.textProvider.SetText(text) // calls refresh
}

и отмечаю, что l.Text также является строкой. Назначения в Go не являются потокобезопасными, поэтому для меня очевидно, что если два потока сражаются за текст метки и оба вызывают label.SetText одновременно, я могу ожидать повреждения памяти.

«Но вы бы этого не сделали», можно сказать. Нет, но меня беспокоит случай, когда кто-то редактирует содержимое записи, в то время как поток приложения решает, что ему нужно заменить весь текст записи - это вполне возможно в моем приложении, поскольку он поддерживает одновременное редактирование несколькими пользователями по сети, поэтому обновления для всех видов виджетов приходят асинхронно. (Обратите внимание, мне все равно, что произойдет, если два человека отредактируют одну и ту же запись одновременно; чьи-то изменения будут потеряны, а мне все равно, кто это. Но это не должно привести к повреждению памяти.) Обратите внимание, что один подход я мог бы Взять, чтобы фоновый поток создал совершенно новый виджет Entry, который затем заменил бы тот в текущем Box. Но этот поток безопасен?

Не то, чтобы я не знал, как сериализовать вещи с каналами. Но я надеялся, что Файн устранит необходимость в этом (сообщение в блоге утверждает, что это так); и даже используя каналы, я не могу убедить себя в том, что пользователь, вмешивающийся в виджет различными способами, в то время как какой-то фоновый поток изменяет его, скрывает его и т. д. c, не приведет к сбоям. Может быть, все, что сериализовано под обложками и совершенно безопасно, но я не хочу выяснять, каким трудным для него является это, потому что у меня не будет способа это исправить.

Файн, очевидно, довольно новичок и, кажется, имеет много обещаний, но документация кажется легкой в ​​деталях. Где-то больше информации? Люди пробовали это успешно?

1 Ответ

4 голосов
/ 14 января 2020

Вы нашли здесь некоторые условия гонки. Есть планы по улучшению, но выпуск 1.2 был необходим, чтобы сначала получить новый "BaseWidget" - и он был выпущен всего через несколько недель go.

  1. Установка полей напрямую в первую очередь для целей настройки и поэтому не предполагается использовать так, как вы иллюстрируете. Тем не менее, мы хотим поддержать это. Базовый виджет вскоре представит что-то похожее на SetFieldsAndRefresh(func()), что обеспечит безопасность переданного кода и обновит sh виджет позже.

  2. В настоящее время действительно существует раса Refresh(). Внутреннее использование каналов было разработано, чтобы удалить это - но есть некоторые углы, такие как множественные программы, вызывающие это. Это та область, в которой наш новый код BaseWidget может помочь - поскольку они могут автоматически блокироваться внутри. Использование этого подхода обеспечит многопоточность без каких-либо изменений для разработчика в будущем выпуске.

API до сих пор позволял разработчикам не беспокоиться о многопоточности и работе с любыми процедурами - нам нужно работать внутренне, чтобы сделать его более безопасным - вы совершенно правы. https://github.com/fyne-io/fyne/issues/506

...