Why there is a data race [closed] - go

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 months ago.
Improve this question
I was reading Dave Cheney's post https://dave.cheney.net/2015/11/18/wednesday-pop-quiz-spot-the-race, but couldn't understand why the example contains data race. Can someone explain it to me?

Here's the relevant code from the blog post:
func (rpc *RPC) compute() {
time.Sleep(time.Second)
rpc.result = 42 /* W */
close(rpc.done)
}
func (RPC) version() int {
return 1
}
⋮
go rpc.compute()
version := rpc.version() /* R */
<-rpc.done
The goroutine modifies the caller's rpc.result field at the line notated by /* W */. This is the easy part to understand.
The method call at the line notated by /* R */ is syntactic sugar for (*rpc).version(). The receiver value is copied on the method call, including the result field. The read is concurrent with the write at /* W */ and is therefore a data race. Although the program does not do anything with the copied result field, it's still a data race.
Fix by changing the version() method to use pointer receiver:
func (*RPC) version() int {
return 1
}

Related

go lang map not throwing null pointer [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 months ago.
Improve this question
why this program is not throwing any null pointer exception
https://go.dev/play/p/37reql6Pdb5
eventhough m is null, still accessing on m.
Check out this code snippet:
package main
import "fmt"
func main() {
var m map[string]string = nil
fmt.Println(m) // output: "map[]"
}
This is an intended behavior since nil acts as zero value for many types of variables, including (but not limited to) maps and slices.
Also, there's no such thing in Golang as "Exception". You can check if a value exists in your map using this syntax:
value, found := m["key"]
where the found variable indicates if the value exists in the map.

can you use a primitive or inbuild data types as a method in golang [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
i wanna know if we are able to use inbuild data types as a method for a func in golang, cause whenever I use it as such, it shows an error
You can define methods on built-in types by first wrapping them with your own types, like this:
type MyInteger int
func (my MyInteger) Tell() {
fmt.Println("I'm MyInteger with value", my)
}
func main() {
var my MyInteger = 42
my.Tell()
}
You can try this on the Go Playground, it will print:
I'm MyInteger with value 42
This can be useful if you want to make a built-in type implement an interface. For example, here's how MyInteger would implement the fmt.Stringer interface:
type MyInteger int
func (my MyInteger) String() string {
return "MyInteger " + strconv.Itoa(int(my))
}
func main() {
var my MyInteger = 42
fmt.Println(my)
}

is access to single variable from routines integrity safe? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
Given such a code:
type Test struct {
V int
}
func (t *Test) t() {
t.V += 1
}
func main() {
t := Test{}
for i := 1; i <= 1000000; i++ {
go t.t()
}
for {
fmt.Println(t.V)
time.Sleep(3 * time.Second)
}
}
I hope it is clear, why do I do this test. And the result is never 1000000. It always prints number less than 1000000.. So, only go channels can I use to solve it ?
Why don't I have 1000000 in result ? How to get 1000000 ?
is access to single variable from routines integrity safe?
No. Everything that is racy is not safe. Under no circumstances. Not if is a single variable, not if accessed by an odd number of goroutines and not on Mondays. Never.

What is difference between these functions? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
What difference between the following functions?
func DoSomething(a *A){
b = a
}
func DoSomething(a A){
b = &a
}
First function receives pointer to value of type A. Second receives copy of value of type A. Here's how you call first function:
a := A{...}
DoSomething(&a)
In this case DoSomething receives pointer to original object and can modify it.
And here's call for second function:
a := A{...}
DoSomething(a)
In this case DoSomething receives copy of a, so it can't modify original object(but if original object contains pointers to other structs it can modify them)
func DoSomething(a *A) { // a is a pointer to given argument of type A
b = a // b is a copy of a, which is also the same pointer
// this is useful to change the given object directly
}
func DoSomething(a A) { // a is a copy of the given object type A
b = &a // b is the pointer of a
}
Remember, a pointer is a variable which holds a memory address.

Idiomatic way of handling a goroutine with one "return" value? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
Imagine I want to write a function that returns a random number divided by 2:
func randomIntInHalf() int {
return rand.Int() / 2
}
But then I decide I want to build this function for concurrency so I end up with:
func randomIntInHalf(c chan<- int) {
c <- rand.Int() / 2
}
func main() {
// Generate 10 random ints in parallel
amount := 10
c := make(chan int, amount)
for i := 0; i < amount; i++ {
go randomIntInHalf(c)
}
for i := 0; i < amount; i++ {
fmt.Println(<-c)
}
close(c)
}
I see some issues with this approach. For example, I require the caller to close the channel when it's done generating, making it possible that someone might call the function and leave the channel open indefinitely. It was sort of my understanding that you always want the sender to close the channel. A) is that true and b) is it even possible in this case? Is there a better way to write this code or approach this problem?
And, generally, is there a better, idiomatic approach for running a function in a parallel that only ever writes 1 (or a known N) value to the channel?
Thanks.
You do not need to close channels. Once it goes out of scope, it will be garbage collected. Closing a channel is usually used to send a done notification to the listener. So it is not even possible in your case.
Yours is an idiomatic approach for what you're trying to achieve, but not the only one. Some others (not necessarily idiomatic) that I can think of are:
You can use a shared data structure and populate that from multiple goroutines with explicit synchronization,
You can keep a separate result for each goroutine, and pass in a pointer to it. Each goroutine sets its result without a need for synchronization, and when everything is done, the caller works with the results.

Resources