---------- Forwarded message --------- From: Zhaoxun Yan <yan.zhao...@gmail.com> Date: Mon, May 23, 2022 at 6:05 PM Subject: Re: [go-nuts] Improving safe global variables with generic or inheritance To: Brian Candler <b.cand...@pobox.com>
*That's really essential. For example, using your library, the following code is most definitely *not* race-free:* tmp := v.Load() tmp = tmp + 1 v.Save(tmp) It is race free as long as `tmp` is a local variable. Although you may argue that another goroutine may have already altered v, that is an atomicity issue but won't cause a `panic` or crash. My resolution is to add a "Tick/Increase" method to substitute the above procedure. Also the `value` entry in the struct is in small cases, prohibiting getting accessed when imported, so the side-attack to directly call `v.value` won't pass the compile phase, which is much safer than the conventional `atomic` package. On Mon, May 23, 2022 at 3:11 PM Brian Candler <b.cand...@pobox.com> wrote: > > It's best to be intentional about it and explicitly acquire and release > a mutex around the critical sections of your code - because ultimately, > only your code knows which sections are critical. > > That's really essential. For example, using your library, the following > code is most definitely *not* race-free: > > tmp := v.Load() > tmp = tmp + 1 > v.Save(tmp) > > The mutex has to protect the entire sequence, not the individual load and > save operations. > > On Monday, 23 May 2022 at 07:57:02 UTC+1 axel.wa...@googlemail.com wrote: > >> Just to be clear, are you aware of the sync/atomic package? >> https://pkg.go.dev/sync/atomic >> There are also some changes in there for Go 1.18, specifically the >> addition of some types, so that only atomic operations can be done: >> https://pkg.go.dev/sync/atomic@master >> I mention this because atomic.Value and atomic.Pointer[T] are essentially >> what you are suggesting here. >> >> On Mon, May 23, 2022 at 8:04 AM Zhaoxun Yan <yan.z...@gmail.com> wrote: >> >>> However, as I want to narrow the scope of this type down to generate >>> integer types (as in the commented code), it encountered two obstacles: >>> >>> 1) It is not legal to embed a generic inside a struct, nor can it make >>> generalized computation =+1 >>> >>> 2) Inheritance is not available in golang, so type "Counter" cannot >>> inherit type "Global" and get its methods automatically. I need to repeat >>> Save and Load methods to "Counter". >>> >>> Am I correct? Or can you improve it? >>> >> >> You are correct that there is no way in Go to write a type which gets all >> methods from an embedded field using generics. However, that is a good >> thing. For example, say you could write >> >> type Locked[T any] struct { >> sync.Mutex >> T >> } >> >> And this would get the methods of T and the methods of sync.Mutex. Then a >> user could do >> >> type Counter int64 >> func (c *Counter) Increment() { *c += 1 } >> >> func main() { >> var c Locked[Counter] >> go c.Increment() >> go c.Increment() >> } >> >> And get a data race. That is, a method can modify a value in a way that >> is incompatible with what your wrapper type is trying to do. >> >> That's really the crux of both of the obstacles you mention. You can't >> run arbitrary computations and you can't promote methods, because *not all >> computation and not all methods can be made concurrency safe this way*. >> >> It's best to be intentional about it and explicitly acquire and release a >> mutex around the critical sections of your code - because ultimately, only >> your code knows which sections are critical. >> >> >>> >> -- >>> You received this message because you are subscribed to the Google >>> Groups "golang-nuts" group. >>> To unsubscribe from this group and stop receiving emails from it, send >>> an email to golang-nuts...@googlegroups.com. >>> To view this discussion on the web visit >>> https://groups.google.com/d/msgid/golang-nuts/baa74bff-6688-4d39-843b-c99a4fea2d1an%40googlegroups.com >>> <https://groups.google.com/d/msgid/golang-nuts/baa74bff-6688-4d39-843b-c99a4fea2d1an%40googlegroups.com?utm_medium=email&utm_source=footer> >>> . >>> >> -- > You received this message because you are subscribed to a topic in the > Google Groups "golang-nuts" group. > To unsubscribe from this topic, visit > https://groups.google.com/d/topic/golang-nuts/3javezRHm98/unsubscribe. > To unsubscribe from this group and all its topics, send an email to > golang-nuts+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/golang-nuts/50d6ab3d-46d0-4357-b5fa-d99b73ef2adan%40googlegroups.com > <https://groups.google.com/d/msgid/golang-nuts/50d6ab3d-46d0-4357-b5fa-d99b73ef2adan%40googlegroups.com?utm_medium=email&utm_source=footer> > . > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CADEX6_U0FK%3Dq_tVDWNLzFjfZEu63T7bJCzPWOFQLv6EJU6WQfQ%40mail.gmail.com.