for example, use pthread_create
create two threads, and both of them print "hello world", and my question is how to count how many times "hello world" printed by each thread?
Asked
Active
Viewed 1,144 times
1

zie tan ny
- 71
- 4
2 Answers
3
and my question is how to count how many times "hello world" printed by each thread?
The easy way to do it would be to declare a global atomic counter at the top of your file:
static std::atomic<int> counter = 0;
and then have each thread increment the counter (i.e. ++counter) each time it prints "hello world". Then in your main(), after all of the threads have been joined, you can print out the value counter.

Jeremy Friesner
- 70,199
- 15
- 131
- 234
1
I can show you the code that child thread pass variable to the main thread;
void * thread_func(void *arg)
{
int num = 10; //assume 'num' is the times that child thread printed "hello world"
pthread_exit((void *)num);
}
int main()
{
pthread_t thread;
void * tret;
pthread_create(&thread,NULL,thread_func,NULL);
pthread_join(thread,&tret);
printf("%d\n",(int)tret);
return 0;
}

charlie
- 267
- 1
- 3
- 15
-
pthread_exit((void *)num); - this seems problematic, in that it's casting an int to a pointer, and even if it was doing the correct thing, and returning (void *)&num, it'd be returning a pointer to a local variable, which is invalid after the function returns. – Mark Bessey Nov 19 '15 at 03:42
-
....yes,there is a problem with the type of `num` .The type of `num` should be `long`,but other code is correct.You should return `(void *)num` ,not `(void *)&num`.if you return `(void *)&num`,this will return a porinter to a local variable. – charlie Nov 19 '15 at 03:53
-
Could use `std::intptr_t` or `std::uintptr_t` (but I'd trust it to work just fine as is). Can just `return (void*)num;` too BTW / using `pthread_exit` is optional and extra porting effort if you move off pthreads to e.g. `std::thread` et al. – Tony Delroy Nov 19 '15 at 04:03
-
Regardless of the integer type, casting from an arbitrary integer to a void* is bad form, because it's not portable. On some platform, merely doing that cast with certain integer values will cause undefined behavior. – Mark Bessey Nov 19 '15 at 04:03
-
@MarkBessey: any reference to support that concern? – Tony Delroy Nov 19 '15 at 04:04
-
It's hard to find links to the ISO standards online, but relevant excerpts are in this SO question: http://stackoverflow.com/questions/7822904/is-it-always-safe-to-convert-an-integer-value-to-void-and-back-again-in-posix Note especially that any void * is guaranteed to be convertible to an intptr_t and back, but that arbitrary intptr_t values may not necessarily be safe to convert to void* – Mark Bessey Nov 19 '15 at 04:08
-
@MarkBessey: 5.2/5 seems to contradict you, as I understand it: *A value of integral type or enumeration type can be explicitly converted to a pointer. A pointer converted to an integer of sufficient size (if any such exists on the implementation) and back to the same pointer type will have its original value; **mappings between pointers and integers are otherwise implementation-defined.*** Note that *implementation-defined* is not *undefined*, and implementations do tend to yield the original value for `int`->`void*`->`int`. – Tony Delroy Nov 19 '15 at 04:12
-
Note too that *"A value of integral type or enumeration type can be explicitly converted to a pointer."* is explicitly allowed, and only aspects of the mapping are implementation defined, so *"not necessarily safe"* seems untrue, though you're right that it's not portably correct numerically. – Tony Delroy Nov 19 '15 at 04:15
-
Yeah, bad wording on my part. It's implementation-defined, not undefined, but implementation-defined can cover a whole variety of behaviors, from "it just works", to "casting any integer to pointer whose bit pattern is not a valid pointer will cause an invalid address trap exception". See "trap representations", here: http://www.ibm.com/developerworks/library/pa-ctypes3/ – Mark Bessey Nov 23 '15 at 20:25