Most active commenters

    ←back to thread

    259 points rbanffy | 11 comments | | HN request time: 0.641s | source | bottom
    Show context
    AlexanderDhoore ◴[] No.44003888[source]
    Am I the only one who sort of fears the day when Python loses the GIL? I don't think Python developers know what they’re asking for. I don't really trust complex multithreaded code in any language. Python, with its dynamic nature, I trust least of all.
    replies(19): >>44003924 #>>44003936 #>>44003940 #>>44003943 #>>44003945 #>>44003958 #>>44003971 #>>44004203 #>>44004251 #>>44004431 #>>44004501 #>>44005012 #>>44005100 #>>44005259 #>>44005773 #>>44006165 #>>44007388 #>>44011009 #>>44011917 #
    1. txdv ◴[] No.44003940[source]
    how does the the language being dynamic negatively affect the complexity of multithreading?
    replies(4): >>44003967 #>>44005360 #>>44005981 #>>44006794 #
    2. nottorp ◴[] No.44003967[source]
    Is there so much legacy python multithreaded code anyway?

    Considering everyone knew about the GIL, I'm thinking most people just wouldn't bother.

    replies(1): >>44004034 #
    3. toxik ◴[] No.44004034[source]
    There is, and what's worse, it assumes a global lock will keep things synchronized.
    replies(1): >>44004133 #
    4. rowanG077 ◴[] No.44004133{3}[source]
    Does it? The GIL only ensured each interpreter instruction is atomic. But any group of instruction is not protected. This makes it very hard to rely on the GIL for synchronization unless you really know what you are doing.
    replies(1): >>44004265 #
    5. immibis ◴[] No.44004265{4}[source]
    AFAIK a group of instructions is only non-protected if one of the instructions does I/O. Explicit I/O - page faults don't count.
    replies(1): >>44004683 #
    6. kfrane ◴[] No.44004683{5}[source]
    If I understand that correctly, it would mean that running a function like this on two threads f(1) and f(2) would produce a list of 1 and 2 without interleaving.

      def f(x):
          for _ in range(N):
              l.append(x)
    
    I've tried it out and they start interleaving when N is set to 1000000.
    7. breadwinner ◴[] No.44005360[source]
    When the language is dynamic there is less rigor. Statically checked code is more likely to be correct. When you add threads to "fast and loose" code things get really bad.
    replies(1): >>44005849 #
    8. jaoane ◴[] No.44005849[source]
    Unless your claim is that the same error can happen more times per minute because threading can execute more code in the same timespan, this makes no sense.
    replies(1): >>44007326 #
    9. jerf ◴[] No.44005981[source]
    I have a hypothesis that being dynamic has no particular effect on the complexity of multithreading. I think the apparent effect is a combination of two things: 1. All our dynamic scripting languages in modern use date from the 1990s before this degree of threading was a concern for the languages and 2. It is really hard to retrofit code written for not being threaded to work in a threaded context, and the "deeper" the code in the system the harder it is. Something like CPython is about as "deep" as you can go, so it's really, really hard.

    I think if someone set out to write a new dynamic scripting language today, from scratch, that multithreading it would not pose any particular challenge. Beyond that fact that it's naturally a difficult problem, I mean, but nothing special compared to the many other languages that have implemented threading. It's all about all that code from before the threading era that's the problem, not the threading itself. And Python has a loooot of that code.

    10. rocqua ◴[] No.44006794[source]
    Dynamic(ally typed) languages, by virtue of not requiring strict typing, often lead to more complicated function signatures. Such functions are generally harder to reason about. Because they tend to require inspection of the function to see what is really going on.

    Multithreaded code is incredibly hard to reason about. And reasoning about it becomes a lot easier if you have certain guarantees (e.g. this argument / return value always has this type, so I can always do this to it). Code written in dynamic languages will more often lack such guarantees, because of the complicated signatures. This makes it even harder to reason about Multithreaded code, increasing the risk posed by multithreaded code.

    11. breadwinner ◴[] No.44007326{3}[source]
    Some statically checked languages and tools can catch potential data races at compile time. Example: Rust's ownership and borrowing system enforces thread safety at compile time. Statically typed functional languages like Haskell or OCaml encourage immutability, which reduces shared mutable state — a common source of concurrency bugs. Statically typed code can enforce usage of thread-safe constructs via types (e.g., Sync/Send in Rust or ConcurrentHashMap in Java).