Preemptive Multithreading by using Continuations

Dominic oblivious at web.de
Fri Dec 27 17:58:29 EST 2002


Python continuations can easily be used for
cooperative threading.

But has anyone tried to implement
preemptive threading by using continuations?

I know that Stackless Python has support
for microthreading but I am curious how
easily, it could be done in standard
Python.

My first attempt has been to patch
ceval.c which periodically looks
(every 1000th steps or so...) for a
Python function named "scheduler"
and if it exists, invokes it.
I have not had the time to get it
working correctly.
(while 1:
     pass
still blocks)

The second idea has already been
implemented successfully, though
it is _extremely_ ugly ;-)
I've installed a signal handler
(SIGALRM) which calls certain jobs
in a round-robin style. The jobs
are continuations and keep their
state.
Since the signal module provides only
access to the function alarm
(and not ualarm) that
can only be triggered every
second at a minimum. I used
a separate C program which
sends SIGALRM as fast as possible ;-)
It's fun, but not really nice and
portable...

So my question is: Has anyone
tried or implemented a decent
(well, everything that is better than
my hack ;-)
microthreading package for
standard python?

Ciao,
  Dominic

---------------------------------------

from __future__ import generators

import signal
import sys

jobs=[]
counter0=0
counter1=0

def alarm(arg1,arg2):

	global jobs
	
	job=jobs[0]
	del jobs[0]
	jobs.append(job)

	for x in job():
		break
		

def job0():
	sum=0
	global counter0
	if counter0>0:
		return
	while 1:
		sum=sum+1
		if sum%100000==1:
			print '#',
			sys.stdout.flush()
			#counter0=counter0+1

		if counter0==10:
			break

	globals()['jobs'].remove(job0)
	print sum
	yield None


def job1(p=0):
	sum=0
	global counter1
	if counter1>0:
		return
	while 1:
		sum=sum+1
		if sum%100000==1:
			print '+',
			sys.stdout.flush()
			#counter1=counter1+1

		if counter1==10:
			break

	globals()['jobs'].remove(job1)
	print sum
	yield None


jobs.append(job1)
jobs.append(job0)

signal.signal(signal.SIGALRM,alarm)

while 1:
	if len(jobs)==0:
		break











More information about the Python-list mailing list