>On Sep 2, 2:23 pm, Alain Ketterlin <al...@dpt-info.u-strasbg.fr> >wrote: >> Sorry, you're wrong, at least for POSIX threads: >> >> void pthread_exit(void *value_ptr); >> int pthread_join(pthread_t thread, void **value_ptr); >> >> pthread_exit can pass anything, and that value will be retrieved with >> pthread_join.
In article <bf50c8e1-1476-41e1-b2bc-61e329bfa...@s12g2000yqm.googlegroups.com> Adam Skutt <ask...@gmail.com> wrote: >No, it can only pass a void*, which isn't much better than passing an >int. It is far better than passing an int, although it leaves you with an annoying storage-management issue, and sidesteps any reasonable attempts at type-checking (both of which are of course "par for the course" in C). For instance: struct some_big_value { ... lots of stuff ... }; struct some_big_value storage_management_problem[SIZE]; ... void *func(void *initial_args) { ... #ifdef ONE_WAY_TO_DO_IT pthread_exit(&storage_management_problem[index]); /* NOTREACHED */ #else /* the other way */ return &storage_management_problem[index]; #endif } ... int error; pthread_t threadinfo; pthread_attr_t attr; ... pthread_attr_init(&attr); /* set attributes if desired */ error = pthread_create(&threadinfo, &attr, func, &args_to_func); if (error) { ... handle error ... } else { ... void *rv; result = pthread_join(&threadinfo, &rv); if (rv == PTHREAD_CANCELED) { ... the thread was canceled ... } else { struct some_big_value *ret = rv; ... work with ret->field ... } } (Or, do dynamic allocation, and have a struct with a distinguishing ID followed by a union of multiple possible values, or a flexible array member, or whatever. This means you can pass any arbitrary data structure back, provided you can manage the storage somehow.) >Passing a void* is not equivalent to passing anything, not even >in C. Moreover, specific values are still reserved, like >PTHREAD_CANCELLED. Some manual pages are clearer about this than others. Here is one that I think is not bad: The symbolic constant PTHREAD_CANCELED expands to a constant expression of type (void *), whose value matches no pointer to an object in memory nor the value NULL. So, provided you use pthread_exit() "correctly" (always pass either NULL or the address of some actual object in memory), the special reserved value is different from all of "your" values. (POSIX threads are certainly klunky, but not all *that* badly designed given the constraints.) >>Re. the original question: since you can define your own Thread >>subclass, with wathever attribute you want, I guess there was no need to >>use join() to communicate the result. The Thread's run() can store its >>result in an attribute, and the "client" can get it from the same >>attribute after a successful call to join(). For that matter, you can use the following to get what the OP asked for. (Change all the instance variables to __-prefixed versions if you want them to be Mostly Private.) import threading class ValThread(threading.Thread): "like threading.Thread, but the target function's return val is captured" def __init__(self, group=None, target=None, name=None, args=(), kwargs=None, verbose=None): super(ValThread, self).__init__(group, None, name, None, None, verbose) self.value = None self.target = target self.args = args self.kwargs = {} if kwargs is None else kwargs def run(self): "run the thread" if self.target: self.value = self.target(*self.args, **self.kwargs) def join(self, timeout = None): "join, then return value set by target function" super(ValThread, self).join(timeout) return self.value -- In-Real-Life: Chris Torek, Wind River Systems Intel require I note that my opinions are not those of WRS or Intel Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603 email: gmail (figure it out) http://web.torek.net/torek/index.html
-- http://mail.python.org/mailman/listinfo/python-list