fyne的线程安全在哪里定义?

where is fyne's thread safety defined?

Fyne(以及 Go)的线程安全承诺吸引了我。但现在我越来越擅长阅读 Go,我看到的东西让人相信 API 作为一个整体不是线程安全的,也许从来没有打算如此。所以我试图确定 "thread safe" 在 Fyne 中的含义。

我正在专门查看

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

并注意到 l.Text 也是一个字符串。 Go 中的赋值不是线程安全的,所以对我来说很明显,如果两个线程争夺标签的文本并且同时调用 label.SetText,我可以预期内存损坏。

"But you wouldn't do that",有人可能会说。不,但我担心有人编辑条目的内容,而应用程序线程决定它需要替换所有条目的文本——这在我的应用程序中是完全可能的,因为它支持多个用户通过网络同时编辑,所以对各种小部件的更新是异步进行的。 (请注意,如果两个人同时编辑同一个条目,我不在乎会发生什么;某人的更改将会丢失,我不在乎谁的更改。但这一定不会导致内存损坏。)请注意,我可以采用一种方法采取的方法是让后台线程创建一个全新的 Entry 小部件,然后它将替换当前 Box 中的那个。但是那个线程安全吗?

不是我不知道怎么用频道连载。但我希望 Fyne 可以消除对它的需求(博客 post 声称确实如此);甚至使用频道,我也无法说服自己,当某个后台线程正在更改、隐藏它等时,用户以各种方式干预小部件不会导致崩溃。也许所有这些都在幕后序列化并且非常安全,但我不想通过困难的方式找出它不是,因为我没有办法修复它。

Fyne 显然很新,似乎有很多希望,但文档似乎没有详细说明。某处有更多信息吗?有人试过成功了吗?

您在这里发现了一些竞争条件。有改进的计划,但需要 1.2 版本才能首先获得新的 "BaseWidget" - 几周前才发布。

  1. 直接设置字段主要用于设置目的,因此预计不会以您说明的方式使用。也就是说,我们确实想支持它。基本小部件将很快引入类似于 SetFieldsAndRefresh(func()) 的东西,这将确保传递的代码的安全并在之后刷新小部件。

  2. Refresh()目前确实有一场比赛。内部通道的使用旨在消除这一点 - 但有一些角落,例如多个 goroutines 调用它。这是我们新的 BaseWidget 代码可以提供帮助的领域——因为它们可以在内部自动锁定。使用这种方法将是线程安全的,并且在未来的版本中不会对开发人员进行任何更改。

到目前为止,API 使开发人员不必担心线程和从任何 goroutines 工作——我们确实需要在内部工作以使其更安全——你说得很对。 https://github.com/fyne-io/fyne/issues/506