<br><br><b><i>Santiago Gala &lt;sgala@apache.org&gt;</i></b> wrote:<blockquote class="replbq" style="border-left: 2px solid rgb(16, 16, 255); margin-left: 5px; padding-left: 5px;"> <br><richard.m.tew@gmail.com><br>&gt; <br>&gt; How could you even make something simple as a c-style for loop?  The<br>&gt; index variable would be clobbered by the other thread running the same<br>&gt; code.<br>&gt; <br><br>Well, there is a piece you have not considered: the stack. Each thread<br>shares memory, except the processor registers and the  stack. Local<br>variables are allocated from the stack in most if not all languages,<br>which means the "automatic" (non extern/static) C vars are allocated<br>separatelly for each thread. <br><br></richard.m.tew@gmail.com></blockquote><br>Ahh.&nbsp; OK.&nbsp; I get it.<br><br>So, this, in effect, is kind of like making a process were all the code, globals, and constants exist in "non-read-only" shared libraries.<br><br>Local vars in the "magical"
 stack are kind of like the the non-shared memory areas of the above process.<br><br>Of course, this view does not explain why a stack is called a "stack" and not "thread-private work area".&nbsp; No doubt, there is a very good reason.<br><br>(Something to do with thread-specific function call/return?)<br><br>Now in Python, most code tends to avoid the use of python global variables.<br><br>I presume this coding style is not feasible in C and friends?<br><br><richard.m.tew@gmail.com></richard.m.tew@gmail.com><blockquote class="replbq" style="border-left: 2px solid rgb(16, 16, 255); margin-left: 5px; padding-left: 5px;"><richard.m.tew@gmail.com><br>Any introductory book con languages or<br>compilers should explain how a stack-allocated program works.<br><br></richard.m.tew@gmail.com></blockquote>Any recommendations? :)<br><richard.m.tew@gmail.com></richard.m.tew@gmail.com><br><richard.m.tew@gmail.com></richard.m.tew@gmail.com><blockquote class="replbq" style="border-left:
 2px solid rgb(16, 16, 255); margin-left: 5px; padding-left: 5px;"><richard.m.tew@gmail.com><br>Thread switching is way cheaper than process switching, as the OS needs<br>only to save/restore registers and the stack pointer (and the stack<br>needs to get into cache, etc.). In a process switch, typically all the<br>cache is stale and needs to be refreshed from the new process memory.<br><br></richard.m.tew@gmail.com></blockquote><br>Is thread vs. process switching just an issue of size of data needing to be moved over the CPU-Memory bus, or is there more to it?<br><br>Does a CPU see any difference between a thread and process switch?<br><br><richard.m.tew@gmail.com></richard.m.tew@gmail.com><blockquote class="replbq" style="border-left: 2px solid rgb(16, 16, 255); margin-left: 5px; padding-left: 5px;"><richard.m.tew@gmail.com><br>&gt; I really don't want to fork/spawn/whatever a 2nd/3rd/4th 100MB+ Python<br>&gt; process.<br><br>Take a look into the wide finder code from
 Fredrich Lundh<br>( http://effbot.org/zone/wide-finder.htm ) starting with my code<br>( http://memojo.com/~sgala/blog/2007/09/29/Python-Erlang-Map-Reduce ) ,<br>and you'll see how it can pay to spawn a process for a lot of programs.<br>The timing goes from 1.9 secs  (his optimized serial code, 1GB input) to<br>0.9 secs in a two core machine.<br><br></richard.m.tew@gmail.com></blockquote><br>Wow. Fascinating reading.<br><br>So, each worker thread blocks on IO to it's spawned process thus releasing the Python GIL.<br><br>Did I get that right? (I did not fully understand each line of code..)<br><br>I can see that in some applications, the spawned worker process could be quite small.&nbsp; <br><br><blockquote class="replbq" style="border-left: 2px solid rgb(16, 16, 255); margin-left: 5px; padding-left: 5px;"><richard.m.tew@gmail.com><br>Again, a lot of effort nowadays is not directed towards optimizing<br>"small" problems, but rather to make them scale. Things like "use
 1000<br>machines to count hits per URL for 20000 log files totaling 3TBytes...<br><br><br></richard.m.tew@gmail.com></blockquote><br>Yeah, I get that feeling.<br><richard.m.tew@gmail.com></richard.m.tew@gmail.com><br>It's great for the (cluster endowed) enterprise software developer, but not for those of us trying to make fast interactive single-user/single-machine apps.<br><br><richard.m.tew@gmail.com></richard.m.tew@gmail.com><blockquote class="replbq" style="border-left: 2px solid rgb(16, 16, 255); margin-left: 5px; padding-left: 5px;"><richard.m.tew@gmail.com><br><br>In a very broad summary, it stops using the OS stack for the interpreter<br>internals, so that "microthreads" that can be switched very fast are<br>possible. (Correct my overgeneralized sentence, please)<br><br><br></richard.m.tew@gmail.com></blockquote><richard.m.tew@gmail.com></richard.m.tew@gmail.com>Ahh.<br><br>So, thread / stack switching is fast, but not fast enough for a "Many Threaded" app. 
 <br><br>How, does stackless work then?&nbsp;&nbsp; <br><br>Where are the tasklet's local variables stored?<br><br>It's the same amount of data, right?&nbsp; Why would I run out "stack memory", but not "stackless memory"<br><br>As a side question, can tasklets (like threads) even safely access global (thus shared) variables, given the non-guaranteed order of execution?<br><br><richard.m.tew@gmail.com></richard.m.tew@gmail.com><br>Thank you again,<br>Allen<br><p>&#32;__________________________________________________<br>Do You Yahoo!?<br>Tired of spam?  Yahoo! Mail has the best spam protection around <br>http://mail.yahoo.com