Home | Trees | Indices | Help |
---|
|
Coroutine threading library.
Shrapnel is a cooperative threading library.
When your process starts up, you must spawn a thread to do some work, and then start the event loop. The event loop runs forever processing events until the process exits. An example:
import coro def main(): print 'Hello world!' # This will cause the process to exit. coro.set_exit(0) coro.spawn(main) coro.event_loop()
Every coroutine thread is created with either the new function (which does NOT automatically start the thread) or the spawn function (which DOES automatically start it).
Every thread has a unique numeric ID. You may also set the name of the thread when you create it.
The shrapnel timeout facility allows you to execute a function which will be interrupted if it does finish within a specified period of time. The coro.TimeoutError exception will be raised if the timeout expires. See the with_timeout docstring for more detail.
If the event loop is not running (such as in a non-coro process), a custom version of with_timeout is installed that will operate using SIGALRM so that you may use with_timeout in code that needs to run in non-coro processes (though this is not recommended and should be avoided if possible).
There is a tread-local storage interface available for storing global data this is thread-specific. You instantiate a ThreadLocal instance and you can assign attributes to it that will be specific to that thread. See the ThreadLocal docs for more detail.
By default when you start the event loop, two signal handlers are installed (for SIGTERM and SIGINT). The default signal handler will exit the event loop. You can change this behavior by setting install_signal_handlers to False before starting the event loop.
See coro.signal_handler for more detail on setting coro signal handlers.
Certain socket operations are allowed to try to execute without blocking if they are able to (such as send/receiving data on a local socket or on a high-speed network). However, there is a limit to the number of times a thread is allowed to do this. The default is 4. The default may be changed (set_selfishness) and the value on a per-thread may be changed (coro.coro.set_max_selfish_acts).
Shrapnel uses the tsc_time module for handling time. It uses the TSC value for a stable and high-resolution unit of time. See that module's documentation for more detail.
A thread is always created when you start the event loop that will resynchronize the TSC relationship to accomodate any clock drift (see tick_updater and tsc_time.update_time_relation).
When a thread exits due to an exception, by default a stack trace is printed to stderr. You may install your own callback to handle this situation. See the set_exception_notifier function for more detail.
The shrapnel library provides a mechanism for printing debug information to stderr. The print_stderr function will print a string with a timestamp and the thread number. The write_stderr function writes the string verbatim.
Shrapnel keeps a reference to the "real" stderr (in saved_stderr) and the print_stderr and write_stderr functions always use the real stderr value. A particular reason for doing this is the backdoor module replaces sys.stderr and sys.stdout, but we do not want debug output to go to the interactive session.
Shrapnel has its own profiler that is coro-aware. See coro.profiler for details on how to run the profiler.
|
|||
|
|
|||
InParallelError An error occurred in the in_parallel function. |
|||
event_queue | |||
fifo First-in First-Out container. |
|||
rusage |
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|
|||
FAILURE =
|
|||
SUCCESS =
|
|||
UNAME =
|
|||
__package__ =
|
|||
all_threads =
: A dictionary of all live coroutine objects. |
|||
event_loop_is_running = False
|
|||
event_map =
|
|||
install_signal_handlers = True
|
|||
microseconds = 1000000
|
|||
now = 6412134603272295
|
|||
now_usec = 1329444398561186
|
|||
saved_stderr = <epydoc.docintrospecter._DevNull instance at 0x : The actual stderr object for the process. |
|||
tick_update_interval = 3600
|
|||
ticks_per_sec = 2659636680
|
|||
ticks_per_usec = 2659
|
|
|
Sleep for a period of time. If a thread is interrupted at the exact same time the sleep is finished, it is not defined whether the interrupt or the sleep "wins". Your thread may continue running (with the interrupt rescheduled to try again later), or it may be interrupted.
|
Call a function with a timeout. Additional arguments and keyword arguments provided are passed to the function. This will re-raise any exceptions raised by the function. If a timeout expires, but the function returns before the next pass in the event loop, then the timeout will be diffused. If a coroutine is already scheduled to run (such as if it received a kevent), and the timeout expires, the timeout will be put on "hold" to let the coroutine run and process the data. If the function returns, then the timeout will be defused, otherwise the timeout will be given another chance to fire during the next pass through the event loop. One should note that due to this behavior, if a coroutine is continually receiving kevents, the timeout will never fire until the kevents stop. Nested timeouts will be handled correctly. If an outer timeout fires first, then only the outer except TimeoutError exception handler will catch it. An exception handlers on the inside will be skipped becaue the actual exception is the Interrupted exception until it gets to the original with_timeout frame. Nested timeouts that are set to fire at the exact same time are not defined which one will fire first. Care must be taken to never catch the Interrupted exception within code that is wrapped with a timeout.
Parameters:
|
|
|
|
Execute several functions in parallel. This will block until all functions have returned or raised an exception. If one or more functions raises an exception, then the InParallelError exception will be raised.
|
Install Python threading emulation. It is recommended that you call this at the very beginning of the main script of your application before importing anything else. This will cause the following modules to be emulated:
At this time, no other blocking operations are supported. |
Create a new coroutine object. Additional arguments and keyword arguments will be passed to the given function. This will not start the coroutine. Call the start method on the coroutine to schedule it to run.
|
Add a kevent handler. This is a low-level interface to register a kevent handler.
|
Set the latency warning threshold multiplier. The default latency warning threshold is 0.2 seconds. This will allow you to change the threshold by multiplying the 0.2 value.
|
Spawn a new coroutine. Additional arguments and keyword arguments will be passed to the given function.
|
Updates TSC<->POSIX relation. This is a thread that runs forever. It is responsible for updating the now and now_usec variables every hour. This will take care of any clock drift because our ticks_per_sec variable might be slightly off. This runs once an hour. |
|
|
|
|
|
all_threads: A dictionary of all live coroutine objects. The key is the coroutine ID, and the value is the coroutine object.
|
saved_stderr: The actual stderr object for the process. This normally should not be used. An example of why this exists is because the backdoor replaces sys.stderr while executing user code.
|
Home | Trees | Indices | Help |
---|
Generated by Epydoc 3.0.1 on Thu Feb 16 18:06:43 2012 | http://epydoc.sourceforge.net |