Here is the code:
var timePointer *[]time.Time
func UpdateHolidayList() error {
//updating logic: pulling list of holidays from API
holidaySlice := make([]time.Time, 0)
//appending some holidays of type time.Time to holidaySlice
//now holidaySlice contains a few time.Time values
timePointer = &holidaySlice
return nil
}
func main() {
//run UpdateHoliday every 7 days
go func() {
for {
UpdateHoliday()
time.Sleep(7 * 3600 * time.Hour)
}
}()
}
I have 4 questions:
holidaySlice
is a local variable, is it safe to point a (global) pointer to it?- Is this whole code multi-thread safe?
- After pointing
timePointer
toholidaySlice
, can I access the values viatimePointer
- (If answer to 3. is "yes") The holiday list is constantly changing, so
holidaySlice
will be different each update. Will the values accessed viatimePointer
change accordingly then?
CodePudding user response:
holidaySlice
is a local variable allocated on the heap. Any variable pointing to the same heap location can access the data structure at that location. Whether or not it is safe depends on how you access it. Even if holidaySlice
was not explicitly allocated on the heap, once you make a global variable point to it, Go compiler would detect that it "escapes", so it would allocate that on the heap.
The code is not thread-safe. You are modifying a shared variable (the global variable) without any explicit synchronization, so there is no guarantee on when or if other goroutines will see the updates to that variable.
If you update the contents of the timePointer
array without explicit synchronization, there is no guarantee on when or if other goroutines will see those updates. You have to use synchronization primitives like sync/Mutex
to delimit read/write access to data structures that can be updated/read by multiple goroutines.
CodePudding user response:
As long as your main does not end
timePointer
will have access to the pointer thatholidaySlice
creates - since its heap allocated, compiler will detect its escape and not free the memory.Nope, absolutely not. Look at the sync package
Yes you can. Just remember to iterate using
*timePointer
instead oftimePointer
It will change - but not accordingly. Since you have not done any synchronization - you have no defined way of knowing what data is stored at slice pointed to by
timePointer
when it is read.