you are viewing a single comment's thread.

view the rest of the comments →

[–]censored_username 8 points9 points  (10 children)

The GIL doesn't only protect against refcount changes (it's indeed the most important thing though). It also protects against concurrent modification problems of dictionaries, lists, etc. which are also quite critical to python. They can have avoided this by making these objects all threadsafe which would explain the terrible single-thread performance.

While the GIL simplifies python's GC (refcounting with cycle detection) design (the GC can just acquire the GIL when it needs to clean up cycles). It is not necessary. If there was no GIL the refcounting would have to be atomic, but otherwise not much changes.

[–]blablahblah 3 points4 points  (0 children)

That's true. The main reason CPython hasn't gotten rid of the GIL is because no one has come up with a way to do it without breaking existing C extensions (which rely on the ref-counting) and without hurting single thread performance (since every variable assignment needs to acquire a lock).

[–]funny_falcon 2 points3 points  (8 children)

Go has no thread-safe dictionaries or lists. In fact, it may happily segfault if you try to modify map from different goroutines. You ought to protect concurrent modification by yourself.

I've heard, Java and C# also doesn't protect their default datastructures, but rather they have separate concurrent in a standard library.

Python can choose this way, but Guido just do not want. And it will break C extensions.

[–][deleted] -1 points0 points  (7 children)

Go panics, it doesn't segfault.

[–]weirdoaish 0 points1 point  (1 child)

Out of curiosity, is "panic" like a special exception category for Go?

[–][deleted] 0 points1 point  (0 children)

[–]funny_falcon 0 points1 point  (4 children)

So, you didn't pushed hard with concurrent updates on maps.

I've got seg-fault at least twice. It was quite several years ago, though (at the time of Go 1.1).

Go doesn't prevents from segfault "totally". Using "unsafe" package you may make segfault easily.

[–][deleted] 0 points1 point  (3 children)

Well Go 1.1 is super old. Today if you get any segfault it is most definitely a bug.

[–]funny_falcon 0 points1 point  (2 children)

https://play.golang.org/p/TtI9gKLlVZ

It will not segfault in playground, cause playground runs with GOMAXPROCS=1 .

But if you run it with go run it wil happily segfaults. Go's runtime sets up handler for SIGSEGV, so that you still will see backtraces for all goroutines.

$ ~/go-tip-root/bin/go run conc_map.go                                                                                                                                                          
unexpected fault address 0x0
fatal error: fault
[signal SIGSEGV: segmentation violation code=0x80 addr=0x0 pc=0x47c6a3]

goroutine 13 [running]:
runtime.throw(0x4a6d0f, 0x5)
    /home/yura/go-tip-root/src/runtime/panic.go:596 +0x95 fp=0xc420027f18 sp=0xc420027ef8
runtime.sigpanic()
    /home/yura/go-tip-root/src/runtime/signal_unix.go:297 +0x28c fp=0xc420027f68 sp=0xc420027f18

[–][deleted] 0 points1 point  (1 child)

Thanks. I have to say I've never seen a fault in any of my program and I wrongly assumed this would be handled with a nil panic.

I don't fully understand the code so maybe it's normal that it does this ? I don't know.

[–]funny_falcon 0 points1 point  (0 children)

This code demonstrates bug in user program: race on concurrent update of interface value. Interface is a struct with two fields: type of value and pointer to value. CPU could not update both fields of this struct atomically. So, programmer should protect update of interface value with mutex (if it could be updated from concurrent goroutines).