I'm having trouble passing a pointer to a structure as an argument to a thread cancellation cleanup handler. Here's some sample code that blows up when it hits the compiler. Any idea what I'm doing wrong?
#include <pthread.h>
typedef struct struct_def {
/* data */
} struct_def;
struct_def *ptr_to_struct_def;
void *
thread_function(void *arg)
{
pthread开发者_JS百科_cleanup_push(cleanup, (void *)ptr_to_struct_def); /* correct? */
/* function continues */
}
int
main()
{
int err;
pthread_t tid;
err = pthread_create(&tid1, NULL, thread_function, (void *)1);
/* main continues */
}
The main problem is that you are missing the call to
pthread_cleanup_pop(0)
after the 'function continues' comment. That will make the compiler fail. Check out sample code using push/pop at opengroup.org.
You also have a few other problems there, as pointed out in other answers.
Here is something that at least compiles after fixing all the compiler errors:
#include <pthread.h>
typedef struct struct_def {
/* data */
} struct_def;
struct_def *ptr_to_struct_def;
void cleanup (void *arg)
{
/* Do your cleanup for the thread here */
}
void *
thread_function(void *arg)
{
pthread_cleanup_push(cleanup, (void *)ptr_to_struct_def); /* correct? */
/* Function continues */
pthread_cleanup_pop (0);
}
int
main()
{
int err;
pthread_t tid;
err = pthread_create(&tid, NULL, thread_function, (void *)1);
/* main continues */
}
I don't see the assignment ptr_to_struct_def = &struct_def;
in the code you posted.
Wait ... did you say compiler? If this doesn't compile - post the compiler error. Though I don't think you meant that.
OK, you did mean that :) Thanks to @Gonzalo I looked into the /usr/include/pthread.h
and sure enough the push/pop are macros (at least on Linux here):
# define pthread_cleanup_push(routine, arg) \
do { \
__pthread_cleanup_class __clframe (routine, arg)
...
# define pthread_cleanup_pop(execute) \
__clframe.__setdoit (execute); \
} while (0)
What an unpleasant surprise ...
typedef struct
{
} struct_def;
struct_def *ptr_to_struct_def;
void * thread_function(void *arg)
int main()
{
int err,iResult;
pthread_attr_t sThreadAttr;
iResult = pthread_attr_init(&sThreadAttr);
assert(iResult==0);
pthread_t tid;
err = pthread_create(&tid1, &sThreadAttr, thread_function, (void *)&ptr_to_struct_def);
iResult = pthread_join(sThread, NULL);
assert(iResult==0);
/* main continues */
#else
thread_function();
#endif
// the end
return 0;
}
void * thread_function(void *arg)
{
}
With that code, the ptr_to_struct_def
is undefined/uninitialized that cannot work. It should point to some instance of struct_def
.
Also I think it is quite uncommon to pass (void*)1
for unused arguments, just use 0
if you don't use the value.
pthread_cleanup_push(cleanup, (void *)ptr_to_struct_def);
//-------------------^^^^^^^ where is this function defined/declared?
You don't need the pointer (notice I removed the typedef):
typedef struct struct_def {
/* data */
} struct_def;
struct_def *ptr_to_struct_def;
void *
thread_function(void *arg)
{
pthread_cleanup_push(cleanup, (void *)ptr_to_struct_def); /* correct? */
/* function continues */
}
int
main()
{
int err;
pthread_t tid;
err = pthread_create(&tid1, NULL, thread_function, (void *)1);
/* main continues */
}
精彩评论