Race Conditions
One important thing to consider is that whenever we run multiple functions concurrently, we have no guarantee in what order each instruction in each function will be performed. In many architectures, this is not a problem. Some functions are not connected in any way with other functions, and whatever a function does in its routine does not affect the actions performed in other routines. This is, however, not always true. The first situation we can think of is when some functions need to share the same parameter. Some functions will just read from this parameter, while others will write to this parameter. As we do not know which operation will run first, there is a high likelihood that one function will override the value updated by another function. Let's see an example that explains this situation:
func next(v *int) {   c := *v   *v = c+1 }
This function takes a pointer to an integer as a parameter. It is a pointer because we want to...