Thread pools: How do I use them?
jvns.ca
jvns.ca
So while it appears that everyone here is amazing; that isn't the case: we just tend to have something that we're very good at and comment on it.
The good thing is that you can learn a lot here as long as you don't get sidelined by some of the inane arguments and fighting :)
It helps to try to tackle a project that you don't already know how to accomplish. Then the Q&A can work like a reverse dictionary. You know the answer, and work backwards to find the question. Every stumbling block is a question to ask.
Also, I know that for some things that I write about, I'm not actually an expert on it beforehand. Instead, I see an interesting question, say to myself "hmm, that's interesting, and I don't actually know the answer", go out to Google, books I own, or just try some experimentation out myself, and then comment on what I found. I usually do try to provide sources and some details about what I did when doing this, but I realize that it may sometimes make me look like more of an expert on topics than I actually am. For example, I have a silver badge in JavaScript on StackOverflow, even though I've only ever written a few dozen lines of JavaSript in my life (in fact, I've probably written more lines of it on StackOverflow than off), since I tend to be good at quickly researching and experimenting with a question and providing a good explanation, not because I'm an expert on JavaScript.
So yeah, it's great the Julia writes down her thought and search process while doing this, as it helps people realize that they too can go through the same process and learn new things.
I like structured arguments against a status quo - that's what's really required here. This article is one notch earlier in the mental digestion chain; a kind of experiential report, an extended anecdote. It's harder to tell if the problem is the library or the user. It asks the reader to work more, because they need to go on a journey, rather than just parse an argument.
I enjoy reported experience too, but I have less time for them unless they're specific to something I have a strong interest in. Otherwise, give me the executive summary.
Yes, I read less of the internet than I used to.
But that's kind of refreshing sometimes. It's easy to get cynical about software engineering like I am. And I followed her stream of consciousness a lot better than I follow a lot of recondite technical prose, particularly when it concerns things mired in proprietary abstractions (Java).
While it is good to have more cynical people too (especially for things like software stability), a company that forgets enthusiasm ends up losing its soul.
At that paragraph I immediately thought of http://aadrake.com/command-line-tools-can-be-235x-faster-tha...
> I have been in technology roles for over 17 years
I guess this is what experience gets you, huh.
Since then I've been using this code, which works great across all platforms and Python versions: https://github.com/metachris/pdfx/blob/master/pdfx/threadpoo...
Java/Scala streams look like they would solve most of the problems in the post on their own.
e.g. Java streams
http://radar.oreilly.com/2015/02/java-8-streams-api-and-para...
private void runParallel() {
trades
.stream()
.parallel().forEach(t->doSomething(t) );
}
Java/Scala has a hierarchy of concurrency abstractions, from high level to low level:Streams, Parallel collections, Futures, Actors, Fork/Join, ExecutionContext/ExecutorService, Threadpools, Threads, synchronized, Barriers, Atomic values and many more.
Also the bit that rings home the strongest is just how difficult it is to do trivial things. Even a senior level programmer with ten years of experience has to sit and say, why is this such a pain in the ass?
I guess that's one reason I really like clojure. Core.async has a really hideous API at first glance but using channels and buffers makes doing this sort of thing a lot more enjoyable. Anyway the intent of the article was to dive into abstractions not to suggest more of them so I'll shush.
Witness the unbounded and unconfigurable (though replaceable — at your own risk since you're setting a "private" variable of the pool) queue of Python 3's threadpool: https://hg.python.org/cpython/file/default/Lib/concurrent/fu...
I wonder if a ForkJoinPool [1] would be helpful here as it does work-stealing giving better utilisation.
Although I've read admonitions that they should not be used when doing I/O. [2] That article seems a little ranty and overblown though, so I'd like opinions on that.
1. https://docs.oracle.com/javase/8/docs/api/java/util/concurre... 2. http://coopsoft.com/ar/CalamityArticle.html
https://opencredo.com/introduction-to-akka-streams-getting-s...
I was kinda surprised by how tricky it was to make a Flow that turned ByteStrings into separate String lines, but it seems like the custom GraphStage approach generalizes really well to more complicated stages.
Java 8 made some improvements in code quality and safety and the framework underlies all of the parallel streaming abstractions used going forward.
It's definitely worth learning all of the concurrency abstractions available in the JDK too though!
In the spirit of brainstorming:
1) Abstract out the I/O step so that you can pass around a bunch of lightweight and lazy "I'll get the lines for you when you ask" objects. Then you can safely queue up a large number of them.
2) Choose to break the "job" apart into two parts, and submit the "get lines from filename" jobs into a different, smaller pool, with the results flowing into the larger (CPU-core-limited) pool.
You can use a work pulling set of actors to handle computation after that, or use Akka Streams to provide backpressure, to avoid the OOM problem.
Although python multithreading outside of IO tasks or dropping into C code that drops the GIL isn't going to parallelize, the latter of which is the only way you're going to burn up cores. The API does make it seem simple though.
Even with the GIL, ThreadPools are still fine performance-wise for tasks that release the GIL such as I/O or a number of functions in numpy and scipy.