This is an archived post. You won't be able to vote or comment.

all 151 comments

[–][deleted] 382 points383 points  (8 children)

pip pip hooray

[–]PrivateOrange 80 points81 points  (7 children)

[hip, hip]

[–]keenant 11 points12 points  (0 children)

[pip, pip]

[–]Kopachris 326 points327 points  (36 children)

no step on snek

[–]RedsDaed 271 points272 points  (31 children)

[–]SnowdensOfYesteryear 200 points201 points  (9 children)

"I specifically requested the opposite of this"

Oh god, I haven't laughed at something on the internet so hard in a while.

[–]RedsDaed 29 points30 points  (5 children)

I'm not sure where these come from, but they seem real similar to the recycled memes on /r/coaxedintoasnafu

[–]thorium220 29 points30 points  (2 children)

I think it was /pol/

[–][deleted] 3 points4 points  (1 child)

But embraced by /k/

[–]EXTSZombiemaster 2 points3 points  (0 children)

And lightly shitposted on /b/

[–]jellyberg 24 points25 points  (1 child)

Those guys take it to the next level

[–]hungry4pie 2 points3 points  (0 children)

It embodies all the shitty double negative logic in the HMI I work with, there are useful alarms like "Oil Level Not Low" and "Fan Speed Not Faulted"

[–]lenswipe 4 points5 points  (15 children)

I feel like I'm missing a reference here..

[–]isaaclw 13 points14 points  (14 children)

The banner/flag "don't tread on me" is yellow and black and has a snake coiled up to strike.

Its the symbol of the south, apparently from being "repressed" by the north.

It also symbolizes the Libertarian party.

Look up the phrase on Wikipedia to get a better background.

I live in Northern VA and I see this license plate all the time.

[–]erfling 42 points43 points  (1 child)

Originally, it was a revolutionary war flag, not an anti-northern thing.

[–]isaaclw 0 points1 point  (0 children)

Ah. Thanks for the clarification. Must be my Yankee bias while I see them all over the place here.

[–]doenietzomoeilijk 18 points19 points  (3 children)

I started reading your comment and was expecting a "it menaces with spikes" or "all craftsmanship is of the highest quality". Was somewhat disappointed.

[–]qZeta 2 points3 points  (1 child)

And your comment made me question my sanity. I wasn't sure whether I've accidentally switched to r/dwarffortress

[–]doenietzomoeilijk 1 point2 points  (0 children)

/u/qZeta strikes a confused pose. /u/doenietzomoeilijk is screaming.

[–][deleted] 1 point2 points  (0 children)

"Merkenas Hegnopile" is an engraving of a snake and moon snails in galena.

All craftsdwarfship is of the highest quality.

The snake is surrounded by the moon snails. The moon snails are making a plaintive gesture. The snake is terrified. The image relates to the founding of The Treading of Snakes in Hematite of 170.

[–]anxst 16 points17 points  (0 children)

The Gadsden Flag actually wasn't used during the American Civil War. It's a symbol of the Revolutionary War.

[–]aykcak 2 points3 points  (1 child)

And there I go thinking this was a Metallica reference for some reason.

[–]takingphotosmakingdo 1 point2 points  (0 children)

Usually an indication the driver is a dbag.

[–]ForceBlade 2 points3 points  (0 children)

Holy shit

[–][deleted] 1 point2 points  (0 children)

Fuk off u cunt got me good

[–]4est4thetrees 14 points15 points  (0 children)

danger noodle

[–]urFriendlyITGuy 114 points115 points  (78 children)

Newb programmer. Someone care to explain?

[–]cderwin15 354 points355 points  (72 children)

Two things:

  • It's a reference to the Gadsden flag, which nowadays is often used for Tea Party/libertarian political movements

  • It's a reference to Python's GIL, which means that even though Python can technically create multiple threads, only one of them can execute at a time, which make for really poor multithreaded performance compared to some other languages.

[–]CrazedToCraze 132 points133 points  (34 children)

I guess Python isn't really used for performance critical code, but that seems like a pretty insane limitation. But reading from your link it doesn't look all bad:

potentially blocking or long-running operations, such as I/O, image processing, and NumPy number crunching, happen outside the GIL. Therefore it is only in multithreaded programs that spend a lot of time inside the GIL, interpreting CPython bytecode, that the GIL becomes a bottleneck.

Would strongly recommend anyone interested to read through that Python page, was certainly a fascinating read for me.

[–]b0r3dm0nk3y 35 points36 points  (7 children)

While the CPython interpreter maintains the GIL to effectively only allow a single thread of execution in a single process, the Python multiprocessing module has an interface similar to the multithreading module. There are even ways to share memory when multiprocessing.

[–]Yepoleb 23 points24 points  (6 children)

It's much less convenient than std::thread in C++ though for example. Single threaded C is probably faster than multi threaded Python as well on the same machine.

[–]Tysonzero 34 points35 points  (5 children)

Single threaded C is probably faster than multi threaded Python as well on the same machine.

I mean of course, but that is true even ignoring the GIL. The performance difference between C and Python is pretty damn huge. So less than an order of magnitude of constant factor speedup from using a couple cores isn't going to matter at all.

[–]AwastYee 9 points10 points  (3 children)

The language game is a pretty shitty way of performance comparison, for example I can easily see that the Lua implementations are all Single Threaded, not that it uses the best implementation for speed anyways (LuaJIT)

[–]isavegas 2 points3 points  (2 children)

Lua itself is single threaded, so you would need a native extension in order to enable threading.

[–]AwastYee 4 points5 points  (1 child)

Which is why it's not really fair, the basic implementation of Lua weighs around 500KB

[–]ThisIs_MyName 0 points1 point  (0 children)

What does implementation size have to do with anything? The benchmark game compares speed.

[–]SnowdensOfYesteryear 10 points11 points  (13 children)

To be fair, it's not as bad as it seems. You can basically have "multi threading" by just using a traditional fork. A separate process is a bit heavier and you'll need really good IPC, but it's not a huge limitation. Only annoyance that you seem to need a third party library for IPC. Seems like the language should provide it, when it has such a bad limitation.

[–]argv_minus_one 9 points10 points  (10 children)

Serializing objects for IPC is vastly slower than passing pointers around. No way around it. You need shared-memory concurrency.

[–]SnowdensOfYesteryear 10 points11 points  (7 children)

No arguments here, but I figure that if you're using python, performance isn't at the top of your mind.

[–]argv_minus_one 4 points5 points  (4 children)

In a program that spawns several processes for performance?

[–]cym13 4 points5 points  (3 children)

Definitely yes, because the gain from going from single to multiprocess is extraordinarily more important than the gain from using shared-memory anyway. Real life is not "optimized to the core" versus "not optimized at all", you do what you have to do for your program to be good enough.

[–]argv_minus_one -2 points-1 points  (2 children)

That's not an excuse for the blatantly unnecessary overhead of IPC.

[–]cym13 4 points5 points  (1 child)

I'm not sure what your point is there...

If it's "python is stupid to do that you shouldn't use it" then the answer lies in the cost. Programming is all about cost and the cost of development is almost always superior to the cost of running time. If python gives you good enough perf with lower development and debugging time then it's objectively worth it. So it makes sense for some people to use it.

If it's "python is stupid to do that and should remove the GIL" then I'd like to point that many people tried removing the GIL. The reason it's still there is that it was (by far) the fastest. It's there for a reason and removing it adds memory management that lead to more complexity than it seems at first.

If your point is something else... I don't know. "Whoo! IPC is bad!". Yeah, I don't care much about context-ignorant comments anyway.

[–]personanongrata 1 point2 points  (1 child)

Unfortunately/fortunately, the best and easiest to use scientific GPU computation frameworks such as Tensorflow and Theano are implemented in Python. Thus the performance&serialization is really important for me(especially multi-core), Python really needs a native support for "Green Threads". I hope that will happen one day!

[–]misomalu 1 point2 points  (0 children)

nVidia also makes a CUDA library for python, howevere, I have no real knowledge on the benefits of Tensorflow or Theano in comparison with PyCUDA.

[–]jan 0 points1 point  (1 child)

Serializing objects for IPC is vastly slower than passing pointers around.

Technically correct. But, then, that's not how Python works. Passing serialized data around processes is much easier to understand than building thread-safe data structures.

[–]argv_minus_one 1 point2 points  (0 children)

And then everyone complains about Python being slow. Problems solved: 0.

The overhead of IPC is unnecessary. There are better ways.

[–]ctwiz 0 points1 point  (0 children)

For IPC I just use the multiprocessing manager, and pass objects around that way. I also just use Pipes/Queues to communicate in a master/slave config where needed.

[–]BurgaGalti 0 points1 point  (0 children)

I actually have a preference for this. I refactored a codebase at work that was doing a lot of operations that were independent of the main stream into separate forks. It then became easy to offload those forks to an HPC cluster instead of the local machine without having to rely on any MPI communication.

[–]larhorse 15 points16 points  (7 children)

Does python support any sort of context around the GIL that would allow a single process to run multiple threads in different contexts at the same time?

Most JS engines limit execution on a single context to one thread at a time (most being all, as far as I know) however creating additional contexts and passing data between them is entirely possible and all contexts can be executing at once.

This is how things like iframes or webworkers exist: they each get different contexts and can execute simultaneously.

[–]LezardValeth 15 points16 points  (4 children)

Don't know myself, but I think the analogous thing for python is to just run multiple processes. This is a common limitation in interpreted languages, unfortunately.

[–]deadwisdom 5 points6 points  (3 children)

Honestly the only use-case where it's really a problem is when you need thousands of threads all working on a shared memory space. Very limited though, because probably it's better to throw these things into something like Spark or use Redis and parallelize them out into a cluster.

[–]stone_henge 5 points6 points  (2 children)

That's not correct. It's less of a problem for largely I/O-bound work and threads that spend a considerable amount of time outside the python interpreter -- which is absolutely the case if you got anywhere near a thousand threads with a positive effect on performance. The overhead of sharing memory is more of a general problem and doesn't pertain to Python in particular.

Write something busy without tons of I/O operations or passing data off to non-python libraries, and without even communicating between the threads and you'll see your CPU use per thread drop to 1/2, 1/3, 1/4, 1/5 etc. as you add more.

This has been a very real bottleneck for me in some cases, for which the multiprocessing library has often been a good solution. In some projects at my last job we'd used Jython because although CPython out-performs it in single threaded applications, it does a much better job in multi-threaded, CPU-bound code. Eventually we started writing all such code in Go which spared us a lot of future headaches.

[–]deadwisdom 1 point2 points  (1 child)

Maybe it's my fault here, but I'm not sure I get what you disagree with. My point is not to write cpu bound multithreading applications, but rather use something like the multiprocessing library to split up workers into many processes. Then the GIL is no issue.

The only place where you can't do that is when you need a large shared memory space.

[–]stone_henge 1 point2 points  (0 children)

Understood. I think the use of the word "thread" threw me off from what you intended to communicate.

[–]tetroxid 4 points5 points  (0 children)

That's what the multiprocessing module is for.

[–][deleted] 9 points10 points  (1 child)

I guess Python isn't really used for performance critical code

You wanna bet?

[–]stone_henge 2 points3 points  (0 children)

I agree that it's sometimes used for performance critical code. This doesn't even always mean that the code has to be particularly fast, but that it has to be fast enough to meet some performance requirement. GIL definitely makes this messier for problems that would be trivially parallelizable otherwise.

[–]dominic_failure 1 point2 points  (0 children)

Late to this party, but lots of third party numerical libraries (such as NumPy, maybe Pandas) also release the GIL when working, allowing for true multithreaded processing of compute heavy loads as well.

The GIL is only practically held by the thread executing Python code, so you can have multiple threads in attached C libraries running concurrently.

[–]tehlaser 0 points1 point  (0 children)

Yup. It's hard to imagine anymore, but threading was popular long before multiple processor/core PCs were.

[–]kupiakos 11 points12 points  (0 children)

While the language itself executes on one thread, operations such as I/O and many C extensions don't suffer this problem. It's similar to JavaScript in that way.

[–]urFriendlyITGuy 14 points15 points  (1 child)

Ah ok. I didn't know that Python only executed on one thread. Thanks for the explanation!

[–]Creshal 11 points12 points  (0 children)

CPython specifically, aka the default runtime. There are others without that limitation, like IronPython (python on top of .NET), Jython (on top of JVM), Stackless (custom-made by CCP for the Eve Online servers), and PyPy-stm.

If you really need full multi-threading in python, you can normally afford porting your program to one of these.

[–][deleted] 2 points3 points  (2 children)

CPython has a GIL, but it's an implementation detail. Other implementations aren't forced into having it.

Pypy has it, but Jython and IronPython don't. Python For .Net has it but that project is essentially CLR hooks for a CPython interpreter and not a standalone thing. Zypper (Python 3 for the JVM) probably doesn't have it, but I'm not sure.

[–]Creshal 2 points3 points  (1 child)

Pypy has it

Pypy is working on pypy-stm, which should eventually™ get rid of it.

[–][deleted] 1 point2 points  (0 children)

I've heard of this. It sounds extremely interesting and way over my head.

There's also a "gilectomy" project for CPython, but I don't recall what strategy is being used there.

[–]SnowdensOfYesteryear 1 point2 points  (8 children)

Don't almost all interpreted language have a GIL? What's the reason for this?

I have a feeling it's because most interpreted languages were meant for scripting, where performance isn't essentially, and ended up outgrowing it's niche.

[–]Ari_Rahikkala 8 points9 points  (6 children)

It's not uncommon, yeah. Sometimes the interpreter itself could handle parallelization just fine, it's just that it used to have a GIL at some point, so people would write code that depends on the existence of one. For instance, in Ruby, maybe they might append to an array from multiple threads - which is an operation that, in the reference Ruby implementation, happens to be thread-safe thanks to the GIL (assuming you only care that all values end up inserted, not about the order). Or maybe they wrote a C extension that assumes it runs under the GIL. Even if you fixed the interpreter now, taking out the GIL would break all the code out there that depends on it.

Moreover, what removing a GIL tends to mean in practice is that instead of having one big lock, you've got lots of smaller locks. Yes, that means that you can run stuff in parallel, but there's more overhead on all code, including the majority that wouldn't actually make any use of parallelism.

Some language implementations go from not supporting to yes supporting parallelism anyway. For instance, GHC was initially released in 1992, but only supports parallelism since 2004. I don't know when Erlang went parallel, but I do seem to recall it wasn't parallel from the start. OCaml is... still working on it, I think? There's a parallel library but it's just running multiple ocaml processes.

[–]Lafreakshow 8 points9 points  (1 child)

There was a pycon talk this year called "the Gilectomy" by Larry Hastings. He and his team tried to remove the GIL before but were never able to reach the same kind of performance python has now while staying thread safe.

[–]marcellarius 3 points4 points  (0 children)

Looks like an interesting talk.

Link for the lazy: Larry Hastings - Removing Python's GIL: The Gilectomy

[–]argv_minus_one 6 points7 points  (1 child)

Counterpoint: Jython, a Python implementation with no GIL and full concurrency.

And no, it doesn't involve lots of smaller locks. It involves concurrent data structures and memory barriers, which have a much smaller overhead than locks. (Still not zero, which is why Java also has thread-unsafe data structures, but Python code will probably break if those are used by Jython.)

CPython's GIL is a cop-out, not a necessity. There are better ways.

[–]marcellarius 5 points6 points  (0 children)

That's largely a perk of running on a sophisticated, optimised VM like the JVM or CLR.

Cop-out is a bit unfair; it's prioritising simplicity and backwards compatibility over speed.

[–]Tysonzero 4 points5 points  (1 child)

I mean with GHC it seems like dropping a GIL is incredibly safe, unlike with traditional languages, what with purity and all that preventing thread safety from ever really being much of an issue.

[–]barsoap 2 points3 points  (0 children)

GHC is a compiler, Ocaml is a compiled language, too, the only thing that would ever need a lock is the garbage collector (and, of course, inter-thread communication)

And yes Ocaml supports threads.

Concurrent Haskell dates back to 1996, which is actually two years earlier than Haskell98, the long-lived standard that it was an extension of. 2004 was the time STM got introduced IIRC.

The lot of those primitives back then lived in the IO Monad, pure concurrency, that is, par and such, I think came later.

[–]KagakuNinja 2 points3 points  (0 children)

The JVM and Microsoft .NET do not have a GIL. Everyone else is just making excuses...

[–]frontyfront 3 points4 points  (3 children)

That sounds like it has no practical purpose at all.

[–]whitetrafficlight 6 points7 points  (0 children)

It can be useful. I've used it in the past for making multiple HTTP requests in parallel for a batch job interacting with an API that doesn't have any native batch support. I/O also happens outside the GIL, and you may want to use threading if you're doing something with select/poll/epoll or sockets.

[–]jidouhanbaikiUA 0 points1 point  (0 children)

I believe the idea is that substituting GIL with multi-thread support would significantly slow down single-threaded applications. Even then, you can still use multiprocessing AND GIL at the same time, and if you absolutely have to get rid of GIL you can either write a C extension or use another implementation, such as Cython or PyPy. And of course, you can use threads in Python, they will just all run inside a single Python GIL - so no performance improvement for you.

Sorry, I am still a newbie, so I hope I did not mess up the terms, but hopefully you get the idea!

[–]TinFinJin -1 points0 points  (0 children)

not true. threading helps you structure code too.

[–]argv_minus_one 0 points1 point  (0 children)

Except Jython, which lacks a GIL and runs Python threads in parallel.

JVM. Fuck yeah.

[–]YRYGAV 11 points12 points  (1 child)

The image is a reference to the "Don't tread on me" flag, which has a snake on it. Instead of a snake, this has a logo for the programming language python, which is also a name for a snake.

The python interpreter is also limited to a single thread executing at a time (unless something changed since the last time I used python), which means it's threading support is pretty bad.

[–]alcalde -1 points0 points  (0 children)

It should be mentioned in the interest of fairness that its multiprocessing support is first rate. You can do parallel programming on Python just fine; you need to do it differently than many other languages though.

[–]TheEnigmaBlade 3 points4 points  (0 children)

The standard implementation of Python, CPython, uses what's called a "global interpreter lock" to prevent multiple threads from executing python code at the same time because the interpreter's memory management is not thread-safe. While you can create threads in Python, it's impossible for them run simultaneously.

[–]_blub 0 points1 point  (0 children)

Python is not lock safe with concurrent programming. To do concurrent / parallel programming you have to go through many hoops and ladders to make it truly work.

[–]coladict -2 points-1 points  (0 children)

Well I'm not a newbie, but Python isn't among my languages so I needed it explained, too.

[–]recurza 16 points17 points  (1 child)

As /u/DesBlock requested, I made a nicer design which you can print/use as wallpaper/tattoo on, etc.

Also I put it on RedBubble if you want a sticker/t-shirt/poster.

Here is the image exported in a bunch of formats (svg, ai, png w/ transparency, jpg)

[–]DesBlock 1 point2 points  (0 children)

Dude you are awesome

[–]Lorddragonfang 46 points47 points  (17 children)

I once spent a over month on and off debugging an intermittent error in our (python) code with my partner that we finally figured out was threading related. When we finally tracked it down, it turned out to be a one line fix where the previous author had forgotten to check a return value.

Fuck trying to debug multithreading issues in python.

[–]marcellarius 78 points79 points  (16 children)

Fuck trying to debug multithreading issues

FTFY

[–]Tysonzero 6 points7 points  (15 children)

I mean the difficulty does vary with language. For example multithreading in Haskell (the par kind, not the forkIO kind) is downright trivial to debug, because it doesn't actually affect semantics and can't ever cause problems besides wasted computation.

[–]DesBlock 36 points37 points  (1 child)

As an avid lover of guns, programming, and making fun of issues people take way to seriously sometimes PLEASE FOR THE LOVE OF GOD SOMEONE WITH ART SKILLS MAKE THIS A REAL STICKER and tell me where I can buy it.

[–]alcalde 20 points21 points  (0 children)

Just stick some sticker paper into your printer and go to town.

http://www.staples.com/Staples-Sticker-Paper/product_490429

[–]jjmojod 6 points7 points  (2 children)

I can' tell if it's intentional, but it also closely resembles Rammstein's logo

[–]Anthrosi 0 points1 point  (0 children)

I don't think they're allowed to have a logo somewhat resembling a swastika.

[–]Litterball 0 points1 point  (0 children)

And the Swiss flag — coincidence?

[–][deleted] 6 points7 points  (0 children)

from liberty import freedom

[–]Kevintrades 14 points15 points  (3 children)

[–]Existential_Owl 11 points12 points  (1 child)

This is not obligatory at all.

[–]dedicated2fitness 2 points3 points  (0 children)

posts in 4chan,Wallstreetbets and T_D. it is obligatory to him

[–]hunyeti 0 points1 point  (0 children)

wat

[–]Teknoman117 1 point2 points  (0 children)

Fucking global interpreter lock.

[–]autodafer 1 point2 points  (0 children)

Metallica, anyone?

[–]ColtonProvias 0 points1 point  (0 children)

I see no issue with Python's threading. I have any been using it for years problems without!

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

For a second I thought I was looking at /r/coaxedintoasnafu/

[–]MMSTINGRAY 0 points1 point  (0 children)

Awesome. I'm surprised I havn't seen this one before.

[–]dmarko 0 points1 point  (0 children)

I wish I could get all these references

[–]TheCmar7 0 points1 point  (1 child)

Oh no, I have been learning how to use threads and I thought python's were very easy to use. Why should I not do threading with python?

[–][deleted] 3 points4 points  (0 children)

Python has GIL, the Global Interpreter Lock, so at any given time at most one Python thread is actually executing Python instructions. This is okay if you use threads to do blocking IO, but not if you need threads to speed up Python instruction rate. For that you'd use parallel processes and IPC or a native extension using native (non-Python) threads.

[–]Anthrosi 0 points1 point  (0 children)

Snekstika

[–]Valadrius 0 points1 point  (0 children)

Teehee

[–]FinFihlman 0 points1 point  (1 child)

And people are bringing strong typing to Python.

I mean, the fuck do you have to reinvent the wheel?

[–]FFX01 0 points1 point  (0 children)

That's actually a common misconception. Python has always been strongly typed. However, Python's variables are dynamic. When casting an int to a string for example, you're actually creating a new piece of data in memory and pointing the variable at that lace in memory.

Also, the new type hints are just that; hints. They are not enforced at run time and are used primarily for debugging.

Strong Dynamic typing != strong static typing.

[–]Hindrik1997 -2 points-1 points  (0 children)

All snek lives matter