move sections
[python/dscho.git] / Modules / threadmodule.c
blob016d5a0be78600d2dbcf294bb99332e5297da0d9
2 /* Thread module */
3 /* Interface to Sjoerd's portable C thread library */
5 #include "Python.h"
6 #include "structmember.h" /* offsetof */
8 #ifndef WITH_THREAD
9 #error "Error! The rest of Python is not compiled with thread support."
10 #error "Rerun configure, adding a --with-threads option."
11 #error "Then run `make clean' followed by `make'."
12 #endif
14 #include "pythread.h"
16 static PyObject *ThreadError;
17 static long nb_threads = 0;
19 /* Lock objects */
21 typedef struct {
22 PyObject_HEAD
23 PyThread_type_lock lock_lock;
24 PyObject *in_weakreflist;
25 } lockobject;
27 static void
28 lock_dealloc(lockobject *self)
30 if (self->in_weakreflist != NULL)
31 PyObject_ClearWeakRefs((PyObject *) self);
32 if (self->lock_lock != NULL) {
33 /* Unlock the lock so it's safe to free it */
34 PyThread_acquire_lock(self->lock_lock, 0);
35 PyThread_release_lock(self->lock_lock);
37 PyThread_free_lock(self->lock_lock);
39 PyObject_Del(self);
42 static PyObject *
43 lock_PyThread_acquire_lock(lockobject *self, PyObject *args)
45 int i = 1;
47 if (!PyArg_ParseTuple(args, "|i:acquire", &i))
48 return NULL;
50 Py_BEGIN_ALLOW_THREADS
51 i = PyThread_acquire_lock(self->lock_lock, i);
52 Py_END_ALLOW_THREADS
54 return PyBool_FromLong((long)i);
57 PyDoc_STRVAR(acquire_doc,
58 "acquire([wait]) -> None or bool\n\
59 (acquire_lock() is an obsolete synonym)\n\
60 \n\
61 Lock the lock. Without argument, this blocks if the lock is already\n\
62 locked (even by the same thread), waiting for another thread to release\n\
63 the lock, and return None once the lock is acquired.\n\
64 With an argument, this will only block if the argument is true,\n\
65 and the return value reflects whether the lock is acquired.\n\
66 The blocking operation is not interruptible.");
68 static PyObject *
69 lock_PyThread_release_lock(lockobject *self)
71 /* Sanity check: the lock must be locked */
72 if (PyThread_acquire_lock(self->lock_lock, 0)) {
73 PyThread_release_lock(self->lock_lock);
74 PyErr_SetString(ThreadError, "release unlocked lock");
75 return NULL;
78 PyThread_release_lock(self->lock_lock);
79 Py_INCREF(Py_None);
80 return Py_None;
83 PyDoc_STRVAR(release_doc,
84 "release()\n\
85 (release_lock() is an obsolete synonym)\n\
86 \n\
87 Release the lock, allowing another thread that is blocked waiting for\n\
88 the lock to acquire the lock. The lock must be in the locked state,\n\
89 but it needn't be locked by the same thread that unlocks it.");
91 static PyObject *
92 lock_locked_lock(lockobject *self)
94 if (PyThread_acquire_lock(self->lock_lock, 0)) {
95 PyThread_release_lock(self->lock_lock);
96 return PyBool_FromLong(0L);
98 return PyBool_FromLong(1L);
101 PyDoc_STRVAR(locked_doc,
102 "locked() -> bool\n\
103 (locked_lock() is an obsolete synonym)\n\
105 Return whether the lock is in the locked state.");
107 static PyMethodDef lock_methods[] = {
108 {"acquire_lock", (PyCFunction)lock_PyThread_acquire_lock,
109 METH_VARARGS, acquire_doc},
110 {"acquire", (PyCFunction)lock_PyThread_acquire_lock,
111 METH_VARARGS, acquire_doc},
112 {"release_lock", (PyCFunction)lock_PyThread_release_lock,
113 METH_NOARGS, release_doc},
114 {"release", (PyCFunction)lock_PyThread_release_lock,
115 METH_NOARGS, release_doc},
116 {"locked_lock", (PyCFunction)lock_locked_lock,
117 METH_NOARGS, locked_doc},
118 {"locked", (PyCFunction)lock_locked_lock,
119 METH_NOARGS, locked_doc},
120 {"__enter__", (PyCFunction)lock_PyThread_acquire_lock,
121 METH_VARARGS, acquire_doc},
122 {"__exit__", (PyCFunction)lock_PyThread_release_lock,
123 METH_VARARGS, release_doc},
124 {NULL} /* sentinel */
127 static PyTypeObject Locktype = {
128 PyVarObject_HEAD_INIT(&PyType_Type, 0)
129 "thread.lock", /*tp_name*/
130 sizeof(lockobject), /*tp_size*/
131 0, /*tp_itemsize*/
132 /* methods */
133 (destructor)lock_dealloc, /*tp_dealloc*/
134 0, /*tp_print*/
135 0, /*tp_getattr*/
136 0, /*tp_setattr*/
137 0, /*tp_compare*/
138 0, /*tp_repr*/
139 0, /* tp_as_number */
140 0, /* tp_as_sequence */
141 0, /* tp_as_mapping */
142 0, /* tp_hash */
143 0, /* tp_call */
144 0, /* tp_str */
145 0, /* tp_getattro */
146 0, /* tp_setattro */
147 0, /* tp_as_buffer */
148 Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
149 0, /* tp_doc */
150 0, /* tp_traverse */
151 0, /* tp_clear */
152 0, /* tp_richcompare */
153 offsetof(lockobject, in_weakreflist), /* tp_weaklistoffset */
154 0, /* tp_iter */
155 0, /* tp_iternext */
156 lock_methods, /* tp_methods */
159 static lockobject *
160 newlockobject(void)
162 lockobject *self;
163 self = PyObject_New(lockobject, &Locktype);
164 if (self == NULL)
165 return NULL;
166 self->lock_lock = PyThread_allocate_lock();
167 self->in_weakreflist = NULL;
168 if (self->lock_lock == NULL) {
169 Py_DECREF(self);
170 PyErr_SetString(ThreadError, "can't allocate lock");
171 return NULL;
173 return self;
176 /* Thread-local objects */
178 #include "structmember.h"
180 typedef struct {
181 PyObject_HEAD
182 PyObject *key;
183 PyObject *args;
184 PyObject *kw;
185 PyObject *dict;
186 } localobject;
188 static PyObject *
189 local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
191 localobject *self;
192 PyObject *tdict;
194 if (type->tp_init == PyBaseObject_Type.tp_init
195 && ((args && PyObject_IsTrue(args))
196 || (kw && PyObject_IsTrue(kw)))) {
197 PyErr_SetString(PyExc_TypeError,
198 "Initialization arguments are not supported");
199 return NULL;
202 self = (localobject *)type->tp_alloc(type, 0);
203 if (self == NULL)
204 return NULL;
206 Py_XINCREF(args);
207 self->args = args;
208 Py_XINCREF(kw);
209 self->kw = kw;
210 self->dict = NULL; /* making sure */
211 self->key = PyString_FromFormat("thread.local.%p", self);
212 if (self->key == NULL)
213 goto err;
215 self->dict = PyDict_New();
216 if (self->dict == NULL)
217 goto err;
219 tdict = PyThreadState_GetDict();
220 if (tdict == NULL) {
221 PyErr_SetString(PyExc_SystemError,
222 "Couldn't get thread-state dictionary");
223 goto err;
226 if (PyDict_SetItem(tdict, self->key, self->dict) < 0)
227 goto err;
229 return (PyObject *)self;
231 err:
232 Py_DECREF(self);
233 return NULL;
236 static int
237 local_traverse(localobject *self, visitproc visit, void *arg)
239 Py_VISIT(self->args);
240 Py_VISIT(self->kw);
241 Py_VISIT(self->dict);
242 return 0;
245 static int
246 local_clear(localobject *self)
248 Py_CLEAR(self->args);
249 Py_CLEAR(self->kw);
250 Py_CLEAR(self->dict);
251 return 0;
254 static void
255 local_dealloc(localobject *self)
257 PyThreadState *tstate;
258 if (self->key
259 && (tstate = PyThreadState_Get())
260 && tstate->interp) {
261 for(tstate = PyInterpreterState_ThreadHead(tstate->interp);
262 tstate;
263 tstate = PyThreadState_Next(tstate))
264 if (tstate->dict &&
265 PyDict_GetItem(tstate->dict, self->key))
266 PyDict_DelItem(tstate->dict, self->key);
269 Py_XDECREF(self->key);
270 local_clear(self);
271 Py_TYPE(self)->tp_free((PyObject*)self);
274 static PyObject *
275 _ldict(localobject *self)
277 PyObject *tdict, *ldict;
279 tdict = PyThreadState_GetDict();
280 if (tdict == NULL) {
281 PyErr_SetString(PyExc_SystemError,
282 "Couldn't get thread-state dictionary");
283 return NULL;
286 ldict = PyDict_GetItem(tdict, self->key);
287 if (ldict == NULL) {
288 ldict = PyDict_New(); /* we own ldict */
290 if (ldict == NULL)
291 return NULL;
292 else {
293 int i = PyDict_SetItem(tdict, self->key, ldict);
294 Py_DECREF(ldict); /* now ldict is borrowed */
295 if (i < 0)
296 return NULL;
299 Py_CLEAR(self->dict);
300 Py_INCREF(ldict);
301 self->dict = ldict; /* still borrowed */
303 if (Py_TYPE(self)->tp_init != PyBaseObject_Type.tp_init &&
304 Py_TYPE(self)->tp_init((PyObject*)self,
305 self->args, self->kw) < 0) {
306 /* we need to get rid of ldict from thread so
307 we create a new one the next time we do an attr
308 acces */
309 PyDict_DelItem(tdict, self->key);
310 return NULL;
315 /* The call to tp_init above may have caused another thread to run.
316 Install our ldict again. */
317 if (self->dict != ldict) {
318 Py_CLEAR(self->dict);
319 Py_INCREF(ldict);
320 self->dict = ldict;
323 return ldict;
326 static int
327 local_setattro(localobject *self, PyObject *name, PyObject *v)
329 PyObject *ldict;
331 ldict = _ldict(self);
332 if (ldict == NULL)
333 return -1;
335 return PyObject_GenericSetAttr((PyObject *)self, name, v);
338 static PyObject *
339 local_getdict(localobject *self, void *closure)
341 if (self->dict == NULL) {
342 PyErr_SetString(PyExc_AttributeError, "__dict__");
343 return NULL;
346 Py_INCREF(self->dict);
347 return self->dict;
350 static PyGetSetDef local_getset[] = {
351 {"__dict__", (getter)local_getdict, (setter)NULL,
352 "Local-data dictionary", NULL},
353 {NULL} /* Sentinel */
356 static PyObject *local_getattro(localobject *, PyObject *);
358 static PyTypeObject localtype = {
359 PyVarObject_HEAD_INIT(NULL, 0)
360 /* tp_name */ "thread._local",
361 /* tp_basicsize */ sizeof(localobject),
362 /* tp_itemsize */ 0,
363 /* tp_dealloc */ (destructor)local_dealloc,
364 /* tp_print */ 0,
365 /* tp_getattr */ 0,
366 /* tp_setattr */ 0,
367 /* tp_compare */ 0,
368 /* tp_repr */ 0,
369 /* tp_as_number */ 0,
370 /* tp_as_sequence */ 0,
371 /* tp_as_mapping */ 0,
372 /* tp_hash */ 0,
373 /* tp_call */ 0,
374 /* tp_str */ 0,
375 /* tp_getattro */ (getattrofunc)local_getattro,
376 /* tp_setattro */ (setattrofunc)local_setattro,
377 /* tp_as_buffer */ 0,
378 /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
379 /* tp_doc */ "Thread-local data",
380 /* tp_traverse */ (traverseproc)local_traverse,
381 /* tp_clear */ (inquiry)local_clear,
382 /* tp_richcompare */ 0,
383 /* tp_weaklistoffset */ 0,
384 /* tp_iter */ 0,
385 /* tp_iternext */ 0,
386 /* tp_methods */ 0,
387 /* tp_members */ 0,
388 /* tp_getset */ local_getset,
389 /* tp_base */ 0,
390 /* tp_dict */ 0, /* internal use */
391 /* tp_descr_get */ 0,
392 /* tp_descr_set */ 0,
393 /* tp_dictoffset */ offsetof(localobject, dict),
394 /* tp_init */ 0,
395 /* tp_alloc */ 0,
396 /* tp_new */ local_new,
397 /* tp_free */ 0, /* Low-level free-mem routine */
398 /* tp_is_gc */ 0, /* For PyObject_IS_GC */
401 static PyObject *
402 local_getattro(localobject *self, PyObject *name)
404 PyObject *ldict, *value;
406 ldict = _ldict(self);
407 if (ldict == NULL)
408 return NULL;
410 if (Py_TYPE(self) != &localtype)
411 /* use generic lookup for subtypes */
412 return PyObject_GenericGetAttr((PyObject *)self, name);
414 /* Optimization: just look in dict ourselves */
415 value = PyDict_GetItem(ldict, name);
416 if (value == NULL)
417 /* Fall back on generic to get __class__ and __dict__ */
418 return PyObject_GenericGetAttr((PyObject *)self, name);
420 Py_INCREF(value);
421 return value;
424 /* Module functions */
426 struct bootstate {
427 PyInterpreterState *interp;
428 PyObject *func;
429 PyObject *args;
430 PyObject *keyw;
431 PyThreadState *tstate;
434 static void
435 t_bootstrap(void *boot_raw)
437 struct bootstate *boot = (struct bootstate *) boot_raw;
438 PyThreadState *tstate;
439 PyObject *res;
441 tstate = boot->tstate;
442 tstate->thread_id = PyThread_get_thread_ident();
443 _PyThreadState_Init(tstate);
444 PyEval_AcquireThread(tstate);
445 nb_threads++;
446 res = PyEval_CallObjectWithKeywords(
447 boot->func, boot->args, boot->keyw);
448 if (res == NULL) {
449 if (PyErr_ExceptionMatches(PyExc_SystemExit))
450 PyErr_Clear();
451 else {
452 PyObject *file;
453 PySys_WriteStderr(
454 "Unhandled exception in thread started by ");
455 file = PySys_GetObject("stderr");
456 if (file)
457 PyFile_WriteObject(boot->func, file, 0);
458 else
459 PyObject_Print(boot->func, stderr, 0);
460 PySys_WriteStderr("\n");
461 PyErr_PrintEx(0);
464 else
465 Py_DECREF(res);
466 Py_DECREF(boot->func);
467 Py_DECREF(boot->args);
468 Py_XDECREF(boot->keyw);
469 PyMem_DEL(boot_raw);
470 nb_threads--;
471 PyThreadState_Clear(tstate);
472 PyThreadState_DeleteCurrent();
473 PyThread_exit_thread();
476 static PyObject *
477 thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
479 PyObject *func, *args, *keyw = NULL;
480 struct bootstate *boot;
481 long ident;
483 if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3,
484 &func, &args, &keyw))
485 return NULL;
486 if (!PyCallable_Check(func)) {
487 PyErr_SetString(PyExc_TypeError,
488 "first arg must be callable");
489 return NULL;
491 if (!PyTuple_Check(args)) {
492 PyErr_SetString(PyExc_TypeError,
493 "2nd arg must be a tuple");
494 return NULL;
496 if (keyw != NULL && !PyDict_Check(keyw)) {
497 PyErr_SetString(PyExc_TypeError,
498 "optional 3rd arg must be a dictionary");
499 return NULL;
501 boot = PyMem_NEW(struct bootstate, 1);
502 if (boot == NULL)
503 return PyErr_NoMemory();
504 boot->interp = PyThreadState_GET()->interp;
505 boot->func = func;
506 boot->args = args;
507 boot->keyw = keyw;
508 boot->tstate = _PyThreadState_Prealloc(boot->interp);
509 if (boot->tstate == NULL) {
510 PyMem_DEL(boot);
511 return PyErr_NoMemory();
513 Py_INCREF(func);
514 Py_INCREF(args);
515 Py_XINCREF(keyw);
516 PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
517 ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
518 if (ident == -1) {
519 PyErr_SetString(ThreadError, "can't start new thread");
520 Py_DECREF(func);
521 Py_DECREF(args);
522 Py_XDECREF(keyw);
523 PyThreadState_Clear(boot->tstate);
524 PyMem_DEL(boot);
525 return NULL;
527 return PyInt_FromLong(ident);
530 PyDoc_STRVAR(start_new_doc,
531 "start_new_thread(function, args[, kwargs])\n\
532 (start_new() is an obsolete synonym)\n\
534 Start a new thread and return its identifier. The thread will call the\n\
535 function with positional arguments from the tuple args and keyword arguments\n\
536 taken from the optional dictionary kwargs. The thread exits when the\n\
537 function returns; the return value is ignored. The thread will also exit\n\
538 when the function raises an unhandled exception; a stack trace will be\n\
539 printed unless the exception is SystemExit.\n");
541 static PyObject *
542 thread_PyThread_exit_thread(PyObject *self)
544 PyErr_SetNone(PyExc_SystemExit);
545 return NULL;
548 PyDoc_STRVAR(exit_doc,
549 "exit()\n\
550 (PyThread_exit_thread() is an obsolete synonym)\n\
552 This is synonymous to ``raise SystemExit''. It will cause the current\n\
553 thread to exit silently unless the exception is caught.");
555 static PyObject *
556 thread_PyThread_interrupt_main(PyObject * self)
558 PyErr_SetInterrupt();
559 Py_INCREF(Py_None);
560 return Py_None;
563 PyDoc_STRVAR(interrupt_doc,
564 "interrupt_main()\n\
566 Raise a KeyboardInterrupt in the main thread.\n\
567 A subthread can use this function to interrupt the main thread."
570 static lockobject *newlockobject(void);
572 static PyObject *
573 thread_PyThread_allocate_lock(PyObject *self)
575 return (PyObject *) newlockobject();
578 PyDoc_STRVAR(allocate_doc,
579 "allocate_lock() -> lock object\n\
580 (allocate() is an obsolete synonym)\n\
582 Create a new lock object. See LockType.__doc__ for information about locks.");
584 static PyObject *
585 thread_get_ident(PyObject *self)
587 long ident;
588 ident = PyThread_get_thread_ident();
589 if (ident == -1) {
590 PyErr_SetString(ThreadError, "no current thread ident");
591 return NULL;
593 return PyInt_FromLong(ident);
596 PyDoc_STRVAR(get_ident_doc,
597 "get_ident() -> integer\n\
599 Return a non-zero integer that uniquely identifies the current thread\n\
600 amongst other threads that exist simultaneously.\n\
601 This may be used to identify per-thread resources.\n\
602 Even though on some platforms threads identities may appear to be\n\
603 allocated consecutive numbers starting at 1, this behavior should not\n\
604 be relied upon, and the number should be seen purely as a magic cookie.\n\
605 A thread's identity may be reused for another thread after it exits.");
607 static PyObject *
608 thread__count(PyObject *self)
610 return PyInt_FromLong(nb_threads);
613 PyDoc_STRVAR(_count_doc,
614 "_count() -> integer\n\
617 Return the number of currently running Python threads, excluding \n\
618 the main thread. The returned number comprises all threads created\n\
619 through `start_new_thread()` as well as `threading.Thread`, and not\n\
620 yet finished.\n\
622 This function is meant for internal and specialized purposes only.\n\
623 In most applications `threading.enumerate()` should be used instead.");
625 static PyObject *
626 thread_stack_size(PyObject *self, PyObject *args)
628 size_t old_size;
629 Py_ssize_t new_size = 0;
630 int rc;
632 if (!PyArg_ParseTuple(args, "|n:stack_size", &new_size))
633 return NULL;
635 if (new_size < 0) {
636 PyErr_SetString(PyExc_ValueError,
637 "size must be 0 or a positive value");
638 return NULL;
641 old_size = PyThread_get_stacksize();
643 rc = PyThread_set_stacksize((size_t) new_size);
644 if (rc == -1) {
645 PyErr_Format(PyExc_ValueError,
646 "size not valid: %zd bytes",
647 new_size);
648 return NULL;
650 if (rc == -2) {
651 PyErr_SetString(ThreadError,
652 "setting stack size not supported");
653 return NULL;
656 return PyInt_FromSsize_t((Py_ssize_t) old_size);
659 PyDoc_STRVAR(stack_size_doc,
660 "stack_size([size]) -> size\n\
662 Return the thread stack size used when creating new threads. The\n\
663 optional size argument specifies the stack size (in bytes) to be used\n\
664 for subsequently created threads, and must be 0 (use platform or\n\
665 configured default) or a positive integer value of at least 32,768 (32k).\n\
666 If changing the thread stack size is unsupported, a ThreadError\n\
667 exception is raised. If the specified size is invalid, a ValueError\n\
668 exception is raised, and the stack size is unmodified. 32k bytes\n\
669 currently the minimum supported stack size value to guarantee\n\
670 sufficient stack space for the interpreter itself.\n\
672 Note that some platforms may have particular restrictions on values for\n\
673 the stack size, such as requiring a minimum stack size larger than 32kB or\n\
674 requiring allocation in multiples of the system memory page size\n\
675 - platform documentation should be referred to for more information\n\
676 (4kB pages are common; using multiples of 4096 for the stack size is\n\
677 the suggested approach in the absence of more specific information).");
679 static PyMethodDef thread_methods[] = {
680 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
681 METH_VARARGS,
682 start_new_doc},
683 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
684 METH_VARARGS,
685 start_new_doc},
686 {"allocate_lock", (PyCFunction)thread_PyThread_allocate_lock,
687 METH_NOARGS, allocate_doc},
688 {"allocate", (PyCFunction)thread_PyThread_allocate_lock,
689 METH_NOARGS, allocate_doc},
690 {"exit_thread", (PyCFunction)thread_PyThread_exit_thread,
691 METH_NOARGS, exit_doc},
692 {"exit", (PyCFunction)thread_PyThread_exit_thread,
693 METH_NOARGS, exit_doc},
694 {"interrupt_main", (PyCFunction)thread_PyThread_interrupt_main,
695 METH_NOARGS, interrupt_doc},
696 {"get_ident", (PyCFunction)thread_get_ident,
697 METH_NOARGS, get_ident_doc},
698 {"_count", (PyCFunction)thread__count,
699 METH_NOARGS, _count_doc},
700 {"stack_size", (PyCFunction)thread_stack_size,
701 METH_VARARGS,
702 stack_size_doc},
703 {NULL, NULL} /* sentinel */
707 /* Initialization function */
709 PyDoc_STRVAR(thread_doc,
710 "This module provides primitive operations to write multi-threaded programs.\n\
711 The 'threading' module provides a more convenient interface.");
713 PyDoc_STRVAR(lock_doc,
714 "A lock object is a synchronization primitive. To create a lock,\n\
715 call the PyThread_allocate_lock() function. Methods are:\n\
717 acquire() -- lock the lock, possibly blocking until it can be obtained\n\
718 release() -- unlock of the lock\n\
719 locked() -- test whether the lock is currently locked\n\
721 A lock is not owned by the thread that locked it; another thread may\n\
722 unlock it. A thread attempting to lock a lock that it has already locked\n\
723 will block until another thread unlocks it. Deadlocks may ensue.");
725 PyMODINIT_FUNC
726 initthread(void)
728 PyObject *m, *d;
730 /* Initialize types: */
731 if (PyType_Ready(&localtype) < 0)
732 return;
734 /* Create the module and add the functions */
735 m = Py_InitModule3("thread", thread_methods, thread_doc);
736 if (m == NULL)
737 return;
739 /* Add a symbolic constant */
740 d = PyModule_GetDict(m);
741 ThreadError = PyErr_NewException("thread.error", NULL, NULL);
742 PyDict_SetItemString(d, "error", ThreadError);
743 Locktype.tp_doc = lock_doc;
744 if (PyType_Ready(&Locktype) < 0)
745 return;
746 Py_INCREF(&Locktype);
747 PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
749 Py_INCREF(&localtype);
750 if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
751 return;
753 nb_threads = 0;
755 /* Initialize the C thread library */
756 PyThread_init_thread();