我试图用pthreads模拟C中的回调机制。我的代码如下:
#include <stdio.h>
#include <pthread.h>
struct fopen_struct {
char *filename;
char *mode;
void *(*callback) (FILE *);
};
void *fopen_callback(FILE *);
void fopen_t(void *(*callback)(FILE *), const char *, const char *);
void *__fopen_t__(void *);
void fopen_t(void *(*callback)(FILE *), const char *filename, const char *mode) {
struct fopen_struct args;
args.filename = filename;
args.mode = mode;
args.callback = callback;
pthread_t thread;
pthread_create(&thread, NULL, &__fopen_t__, &args);
}
void *__fopen_t__(void *ptr) {
struct fopen_struct *args = (struct fopen_struct *)ptr;
FILE *result = fopen(args -> filename, args -> mode);
args -> callback(result);
}
int main() {
fopen_t(&fopen_callback, "test.txt", "r");
}
void *fopen_callback(FILE *stream) {
if (stream != NULL)
printf("Opened file successfully\n");
else
printf("Error\n");
}
这会编译,但在执行时,它会在屏幕上没有错误或消息的情况下完成。我错过了什么?
答案 0 :(得分:3)
main
线程在完成__fopen_t__
之前退出。因此要么使用pthread_detach
分离该线程( fopen_t )并执行其他有用的操作,要么等待使用__fopen_t__
完成pthread_join
。
使用pthread_join
时,您的fopen_t
可能会显示,
void fopen_t(void *(*callback)(FILE *), const char *filename, const char *mode)
{
struct fopen_struct args;
args.filename = filename;
args.mode = mode;
args.callback = callback;
pthread_t thread;
pthread_create(&thread, NULL, &__fopen_t__, &args);
pthread_join( thread, NULL ); // Waiting till the new thread completes
}
有关详细信息,请参阅手册页pthread_detach和pthread_join。
根据R ..的评论更合乎逻辑,动态分配的代码如下所示。
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
struct fopen_struct {
char *filename;
char *mode;
void *(*callback) (FILE *);
};
void *fopen_callback(FILE *);
pthread_t* fopen_t(void *(*callback)(FILE *), const char *, const char *);
void *__fopen_t__(void *);
// returns pthread_t* to be freed by caller
pthread_t* fopen_t(void *(*callback)(FILE *), const char *filename, const char *mode)
{
struct fopen_struct *args = calloc( 1, sizeof( struct fopen_struct ) );
args->filename = filename;
args->mode = mode;
args->callback = callback;
pthread_t *thread = calloc( 1, sizeof( pthread_t ) ); // Need error checks
pthread_create( thread, NULL, &__fopen_t__, args);
//pthread_join( thread, NULL ); // `thread` is returned to caller
return thread;
}
// takes `struct fopen_struct*` as argument and will be freed
void *__fopen_t__(void *ptr) {
struct fopen_struct *args = (struct fopen_struct *)ptr;
FILE *result = fopen(args -> filename, args -> mode);
args -> callback(result);
free( args ); args = NULL;
return NULL;
}
int main() {
pthread_t *th_id = NULL;
th_id = fopen_t(&fopen_callback, "test.txt", "r"); // Need error checks
pthread_join( *th_id, NULL ); // Wait till the __fopen_t__ thread finishes
free( th_id ); th_id = NULL;
return 0;
}
答案 1 :(得分:0)
在main的底部添加sleep()
。也许你的程序在获得结果之前就完成了。
其他评论
这是注意这个错误最简单的方法,但不是正确的方法。 :)