问题
I try to add a section to my code which is able to unlock the mutex in a case of cancellation. This may happen and would cause a deadlock. Therefore I tried to add pthread_cleanup_push(cleanup_unlock_mutex, &mutex_ftdi);
but this line cause a syntax error from the line where I add it till the end of the code file. If I comment the code line the program will compile without any error.
What I'm doing wrong?
void cleanup_unlock_mutex(void *p){
pthread_mutex_unlock(p);
}
....... }else{
for(unsigned count=0; count <= number_of_requests; count++){
pthread_cleanup_push(cleanup_unlock_mutex, &mutex_ftdi);
pthread_mutex_lock(&mutex_ftdi);
process_requests(count, numberofthread);
pthread_mutex_unlock(&mutex_ftdi);
}
} // compiler error: error: expected ‘while’ before ‘}’ token
..........
All other functions in the file get the warning: ISO C forbids nested functions [-pedantic].
回答1:
You must call pthread_cleanup_push()
and pthread_cleanup_pop()
in matching pairs, and your snippet doesn't have the pthread_cleanup_pop()
call.
The docs at http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_cleanup_pop.html explain why:
These functions may be implemented as macros. The application shall ensure that they appear as statements, and in pairs within the same lexical scope (that is, the
pthread_cleanup_push()
macro may be thought to expand to a token list whose first token is'{'
withpthread_cleanup_pop()
expanding to a token list whose last token is the corresponding'}'
).
To make this concrete, one possible implementation, taken from glibc's nptl/sysdeps/pthread/pthread.h
:
/* Install a cleanup handler: ROUTINE will be called with arguments ARG
when the thread is canceled or calls pthread_exit. ROUTINE will also
be called with arguments ARG when the matching pthread_cleanup_pop
is executed with non-zero EXECUTE argument.
pthread_cleanup_push and pthread_cleanup_pop are macros and must always
be used in matching pairs at the same nesting level of braces. */
# define pthread_cleanup_push(routine, arg) \
do { \
__pthread_cleanup_class __clframe (routine, arg)
/* Remove a cleanup handler installed by the matching pthread_cleanup_push.
If EXECUTE is non-zero, the handler function is called. */
# define pthread_cleanup_pop(execute) \
__clframe.__setdoit (execute); \
} while (0)
来源:https://stackoverflow.com/questions/24503877/pthread-cleanup-push-causes-syntax-error