Thanks everybody for the feedback on 'fork'.<br /><br />Let me address the issues and specify it further:<br /><br /><br />1) Process vs. Thread vs. Coroutine<br /><br />From my understanding, the main fallacy here is that the caller would be able to decide which type of pool is best suited.<br /><br />Take create_thumbnail as an example. You do not know whether this is cpu-bound or io-bound; you can just make a guess or try it out.<br /><br />But who knows then? I would say: the callee.<br /><br />create_thumbnail is cpu-bound when doing the work itself on the machine.<br />create_thumbnail is io-bound when delegating the work to, say, a web service.<br /><br /><strong>Same functionality, same name, same API, different pools required.</strong><br /><br /><br />This said, I would propose something like a marking solution:<br /><br /><span style="font-family: 'courier new', courier, monospace;">@cpu_bound</span><br /><span style="font-family: 'courier new', courier, monospace;">def create_thumbnail(image):</span><br /><span style="font-family: 'courier new', courier, monospace;">    # impl</span><br /><br /><span style="font-family: 'courier new', courier, monospace;">@io_bound</span><br /><span style="font-family: 'courier new', courier, monospace;">def create_thumbnail(image):</span><br /><span style="font-family: 'courier new', courier, monospace;">    # impl</span><br /><br />(coroutines are already marked as such)<br /><br />From this, the Python interpreter should be able to infer which type of pool is appropriate.<br /><br /><br />2) Pool size<br /><br />Do lists have a fixed length? Do I need to define their lengths right from the start? Do I know them in advance?<br /><br />I think the answers to these questions are obvious. I don't understand why it should be different for the size of the pools. They could grow and shrink depending on the workload and the available resources.<br /><br /><br />3) Pool Management in General<br /><br />There is a reason why I hesitate to explicitly manage pools. Our code runs on a plethora of platforms ranging from few to many hardware threads. We actually do not want to integrate platform-specific properties right into the source. The point of having parallelism and concurrency is to squeeze out more of the machines and get better response times. Anything else wouldn't be honest in my opinion (besides from researching and experimenting).<br /><br />Thus, a practical solution needs to be simple and universal. Explicitly setting the size of the pool is not universal and definitely not easy.<br /><br />It doesn't need to be perfect. Even if a first draft implementation would simply define pools having exactly 4 processes/threads/coroutines, that would be awesome. Even cutting execution time into half would be an amazing accomplishment.<br /><br />Maybe, even 'fork' is too complicated. It could work without it given the decorators above. But then, we could not decide whether to run things in parallel or sequentially. I think I do not like that.<br /><br /><br />4) Keyword 'fork'<br /><br />Well, first shot. If you have a better one, I am all in for it (4 letters or shorter only ;) )... Or maybe something like 'par' for parallel or 'con' for concurrent.<br /><br /><br />5) Awaiting the Completion of Something<br /><br />As Andrew proposed, using the return value should result in blocking.<br /><br />What if there is no result to wait for?<br />That one is harder but I think another keyword like 'wait' or 'await' should work here fine.<br /><br /><span style="font-family: 'courier new', courier, monospace;">for image in images:</span><br /><span style="font-family: 'courier new', courier, monospace;">    fork create_thumbnail(image)</span><br /><span style="font-family: 'courier new', courier, monospace;">wait</span><br /><span style="font-family: 'courier new', courier, monospace;">print(get_size_of_thumbnail_dir())</span><br /><br /><br />6) Exceptions<br /><br />As close to sequential execution as possible.<br /><br />That is, when some function is forked out and raises an exception, it should behave as if it were a normal function call.<br /><br /><span style="font-family: 'courier new', courier, monospace;">for image in images:</span><br /><span style="font-family: 'courier new', courier, monospace;">    fork create_thumbnail(image) # I would like to see that in my stacktrace</span><br /><br />Also true for expressions. '+=' might raise an exception because, say, huge_calculation returns 'None'. Although the actually evaluation of the sum needs to take place only at the print statement, I would like to see the exception raised at the highlighted place:<br /><br /><span style="font-family: 'courier new', courier, monospace;">end_result = 0</span><br /><span style="font-family: 'courier new', courier, monospace;">for items in items_list:</span><br /><span style="font-family: 'courier new', courier, monospace;">    end_result += fork huge_calculation(items) # stacktrace for '+=' should be here</span><br /><span style="font-family: 'courier new', courier, monospace;">print(end_result) # not here</span><br /><br /><br />Best,<br />Sven<br /><br /><br/><hr>FreeMail powered by <a href="https://mail.de" target="_blank">mail.de</a> - <strong>mehr Sicherheit, Seriosität und Komfort</strong>