I understand that there is no support for recursive mutexes in Go (and that a lot of folks consider these dangerous), and that channels are the preferred way to implement complex concurrency patterns.
However, I cannot figure out any sensible way to implement a very common concurrency pattern - that of the re-entrant or recursive critical section.
Roughly: goroutines A and B will compete for a lock over a critical section (say some state in a struct needs to be atomically modified). Let's say A receives the lock. However, A will recurse, possibly needing to enter the critical section many times. When it has exited the critical section as it has entered it, goroutine B will get the lock, etc.
I want to implement this with channels (or in any way possible in Go otherwise), without having to pass some string or token back and forth through the whole call tree of functions that might pass through the critical section (there is no "goroutine id" available)., and without having messy/expensive stack introspection necessary using runtime package.
How can this be done?
Say, your example above looks like:
package main
import "fmt"
type Foo struct {
// here must be reentrant mutex
Value int
}
var F Foo
func A() {
F.Value += 1
if F.Value < 10 {
A()
}
}
func B() {
F.Value += 5
if F.Value < 20 {
A()
}
}
func main() {
F = Foo{
Value: 0,
}
A()
B()
fmt.Println("F is", F.Value)
}
http://play.golang.org/p/STnaLUCaqP
Then implementation in channels should follow simple principle - only one place where F.Value is read or written, wrapped by select statement. Something like this:
package main
import "fmt"
type Foo struct {
Value int
}
var (
F Foo
ch = make(chan int)
)
func A() {
val := <-ch
ch <- val+1
if val < 10 {
A()
}
}
func B() {
val := <-ch
ch <- val+5
if val < 20 {
A()
}
}
func main() {
F = Foo{
Value: 0,
}
go func() {
for {
select {
case val := <-ch:
F.Value = val
case ch <- F.Value:
}
}
}()
A()
B()
fmt.Println("F is", F.Value)
}
http://play.golang.org/p/e5M4vTeet2
Here we use bidirectional buffered channel for getting/setting F.Value. One reader, one writer, select does all the magic to handling access.
You may also be interested in relevant topic in golang-nuts on the reentrant mutexes: https://groups.google.com/forum/#!topic/golang-nuts/vN5ncBdtkcA There are good explanation why reentrant mutexes are not useful in Go (and it's not the question of danger).
Related
I'm dealing with some asynchronous functions and trying to update views. In short I have function 1 with asynchronous function that will return a string to be passed to function 2. I am updating views in both functions, on main thread. It all works but I need to understand if this is correct way.
class A {
var varA = ""
var varB = ""
func f1 (_ completion: #escaping (String) -> void ){
some asynchronous call ... { in
...
DispatchQueue.main.async {
self.varA = "something"
sef.labelA.text = self.varA
completion(self.varA)
}
}
}
func f2 (_ string: String){
another asynchronous call ... { in
...
DispatchQueue.main.async {
self.varB = string
sef.labelB.text = self.varB
}
}
}
// funcation call
f1(completion: f2)
}
Three questions, 1) What is the right way to run a dependent function where there is wait for an asynchronous callback?
2) Is DispatchQueue.main.async needed to update views?
3) Is it ok to call async func in another async callback? Isn't there chance self may be nil in some cases if you are updating views in some escaping function?
I'm going to try helping you according to your questions:
Question 1) There are many right ways and each developer can have its own logic, but in this case, what I personally would probably do is something like this:
class A {
func f1 (_ completion: #escaping (String) -> void ){
some asynchronous call ... { in
...
DispatchQueue.main.async { [weak self] in // 1
guard let strongSelf = self else { return } // 2
let varA = "something" // 3
strongSelf.label.text = varA
completion(varA) // 4
}
}
}
func f2 (_ string: String){
another asynchronous call ... { in
...
DispatchQueue.main.async {
sef.labelB.text = string // 5
}
}
}
// function call
// 6
f1(completion: { [weak self] text in
guard let strongSelf = self else { return }
strongSelf.f2(text)
})
}
1 - Here I'm using [weak self] to avoid retain cycles.
2 - Just unwrapping the optional self, case it's nil, I'll just return.
3 - In your case, it's not really necessary to have class variables, so I'm just creating local variables inside the block.
4 - Finally, I'm calling the completion with the variable containing the string.
5 - I also don't really need to set a class variable in here, so I'm just updating the label text with the string provided as a paramater.
6 - Then, I just need to call the first function and use the completion block to call the second after the first one completes.
Question 2) Yes, you must call DispatchQueue.main to update the view. This way your making sure that your code will be executed in the main thread that is crucial for things interacting with UI because it allow us to have a sincronization point as you can read in Apple's documentation.
Question 3) Using [weak self] and guard let strongSelf = self else { return }, I'm avoiding retain cycles and the cases where self can be nil.
For example
var myStructRef *Vertex
var myStruct Vertex
myStructRef = &Vertex{2, 3}
myStruct = Vertex{2, 3}
fmt.Println(myStructRef)
fmt.Println(myStruct)
changeByReferenceStruct(myStructRef)
changeByValueStruct(myStruct)
fmt.Println(myStructRef)
fmt.Println(myStruct)
And
func changeByValueStruct(myStruct Vertex) {
myStruct.X = 5
fmt.Println(myStruct)
}
func changeByReferenceStruct(myStruct *Vertex) {
myStruct.X = 7
fmt.Println(myStruct)
}
Isn't both myStructRef *Vertex and myStruct Vertex a pointer pointing to the struct itself? Why is there a discrepancy in behavior when I modify the struct in a function?
Is golang creating a new struct in changeByValueStruct when it resolves the parameter?
When you pass a pointer as an argument, what happens under the hood is that a copy of that pointer is created and passed to the underlying function. It should not be confused with pass-by-reference.
Let's look at an example to better grasp it:
package main
import (
"fmt"
)
type Point struct {
x int
y int
}
func (p Point) String() string {
return fmt.Sprintf("(%d, %d)", p.x, p.y)
}
func modifyValue(point Point) {
point.x += 10
}
func modifyPointer(point *Point) {
point.x = 5
point.y = 5
}
func modifyReference(point *Point) {
point = &Point{5, 5}
}
func main() {
p := Point{0, 0}
fmt.Println(p) // prints (0, 0)
modifyValue(p)
fmt.Println(p) // prints (0, 0)
modifyPointer(&p)
fmt.Println(p) // prints (5, 5)
p = Point{0, 0}
modifyReference(&p)
fmt.Println(p) // prints (0, 0)
}
What happens inside the modifyValue function is that a totally different instance of a Point structure is modified, so the value passed when calling the function is unaffected.
In the second example, a pointer to the structure is passed so the fields of the structure can be modified in a way that is visible from outside.
The most interesting point is made by the last function, modifyReference. If you are familiar with the pass by reference paradigm available in other languages you would expect to be able to modify the referenced object altogether, but this doesn't happen. It's because you're modifying a copy of the pointer passed as argument.
You may wonder, if everything is passed by value, when should you pass pointers and when values. Passing values assures the caller function that the passed structure cannot suffer any changes, so when you need this behaviour, go for the value. The downside of this is that a copy of the entire object is made and, if it is too big, memory becomes a concern.
If you're passing a big structure as an argument, using a pointer is better because it saves space, but you lose the guarantee that the object won't suffer any changes.
Passing struct to function argument makes copy of values. And passing pointer of struct doesn't. So passing struct can't update field value.
package main
import (
"fmt"
)
type Foo struct {
value int
}
func PassStruct(foo Foo) {
foo.value = 1
}
func PassStructPointer(foo *Foo) {
foo.value = 1
}
func main() {
var foo Foo
fmt.Printf("before PassStruct: %v\n", foo.value)
PassStruct(foo)
fmt.Printf("after PassStruct: %v\n", foo.value)
fmt.Printf("before PassStructPointer: %v\n", foo.value)
PassStructPointer(&foo)
fmt.Printf("after PassStructPointer: %v\n", foo.value)
}
https://play.golang.org/p/AM__JwyaJa
Is it possible to get the address of a function reference in Go?
Something like
func myFunction() {
}
// ...
unsafe.Pointer(&myFunction)
Just that is does not work that way. My guess it's not possible, but I did not found any proof yet.
Edit: Background
The background of my question comes from dealing with CGO and C Function pointers.
This works:
/*
void go_myFunction();
typedef void (*myFunction_f)();
myFunction_f pMyFunction;
*/
import "C"
//export go_myFunction
func go_myFunction() {
// ...
}
func SetupFp() {
C.pMyFunction = (*[0]byte)(unsafe.Pointer(C.go_myFunction))
}
I'm also aware that the documentation states that passing a pointer to a go function does not work. But the above code seems no to be that far from it. I was just wondering if one could somehow skip the export step.
function type in Go is not addressable and not comparable because:
Function pointers denote the code of the function. And the code of an anonymous function created by function literal is only stored once in memory, no matter how many times the code that returns the anonymous function value runs.
Original answer
If you need to compare addresses of a functions you can do it with reflect.Pointer. But any way this operation is more senseless than impossible because:
If v's Kind is Func, the returned pointer is an underlying code pointer, but not necessarily enough to identify a single function uniquely. The only guarantee is that the result is zero if and only if v is a nil func Value.
You may get the address of a Go function like this:
package main
import (
"fmt"
"reflect"
)
func HelloWorld() {
fmt.Println("Hello, world!")
}
func main() {
var ptr uintptr = reflect.ValueOf(HelloWorld).Pointer()
fmt.Printf("0x%x", ptr)
}
You can get address of function use function GetFuncAddr:
package main
import (
"fmt"
"unsafe"
"reflect"
)
func HelloWorld() {
fmt.Println("Hello, world!")
}
func GetFuncAddr(i interface{}) uintptr {
type IHeader struct {
typ uintptr
word uintptr
}
return (*IHeader)(unsafe.Pointer(&i)).word
}
func main() {
tmp := HelloWorld
ptr1 := *(*uintptr)(unsafe.Pointer(&tmp)) //Way 1
ptr2 := GetFuncAddr(HelloWorld) //Way 2
fmt.Printf("0x%x = 0x%x", ptr1, ptr2)
//Thits is not are functon addrress!!!
BadPTR1 := reflect.ValueOf(HelloWorld).Pointer()
BadPTR2 := **(**uintptr)(unsafe.Pointer(&tmp)) //dereferenced pointer
fmt.Printf("\nBAD: 0x%x = 0x%x", BadPTR1 , BadPTR2 )
}
When methods are defined in Go, does the pointer always increment in the exact order in which they are defined in source - or is it possible that lower pointer space could be re-allocated?
For example - is methods now in the guaranteed order of A, Z, D, B regardless of go version or arch?
package main
import (
"fmt"
"reflect"
"sort"
)
type t struct{}
func (a *t) A() {}
func (a *t) Z() {}
func (a *t) D() {}
func (a *t) B() {}
type addr struct {
Addr uintptr
Method string
}
type addrList []addr
func (a addrList) Len() int {
return len(a)
}
func (a addrList) Less(i, j int) bool {
return a[i].Addr < a[j].Addr
}
func (a addrList) Swap(i, j int) {
a[i], a[j] = a[j], a[i]
}
func main() {
methods := addrList{}
fooType := reflect.TypeOf(&t{})
for i := 0; i < fooType.NumMethod(); i++ {
method := fooType.Method(i)
methods = append(methods, addr{method.Func.Pointer(), method.Name})
}
sort.Sort(methods)
fmt.Println(methods)
}
The Go Programming Language Specification
This is a reference manual for the Go programming language.
The order is not defined in the Go language specification therefore the order is undefined. It's implementation dependent.
I'd like to declare a map that would that would look like this, so I could map various init functions to initType:
func makeMap(){
m := make(map[initType]&InitFunc)
//How should the value declaration be set up for this map?
}
type initType int
const(
A initType = iota
B
C
D
)
func init(aInitType initType){
doStuff(aInitType)
}
func init(aInitType initType){
doOtherStuff(aInitType)
}
func init(aInitType initType){
doMoreStuff(aInitType)
}
How do I declare the function pointer type (which I called &InitFunc in the example because I don't know how to do it) so I can use it as the value in a Map?
Unlike C, you don't actually need a "pointer" to the function, since in Go, functions are reference types, similar to slices, maps, and channels. Further, the address operator, &, produces a pointer to a value, but to declare a pointer type, use *.
You seem to be wanting your InitFunc to take a single InitType and return no values. In that case, you would declare it as:
type InitFunc func(initType)
Now, your map initialization can simply look like:
m := make(map[initType]InitFunc)
A complete example would be (http://play.golang.org/p/tbOHM3GKeC):
package main
import "fmt"
type InitFunc func(initType)
type initType int
const (
A initType = iota
B
C
D
MaxInitType
)
func Init1(t initType) {
fmt.Println("Init1 called with type", t)
}
var initFuncs = map[initType]InitFunc{
A: Init1,
}
func init() {
for t := A; t < MaxInitType; t++ {
f, ok := initFuncs[t]
if ok {
f(t)
} else {
fmt.Println("No function defined for type", t)
}
}
}
func main() {
fmt.Println("main called")
}
Here, it's looping through each initType, and calling the applicable function, if it is defined.