вызов обратного вызова из потока с использованием указателей функций
компилятор программы c gcc
У меня 3 файла. main.c stop_watch.h и stop_watch.c
Эта программа действительно работает. Я вызываю start_stopwatch. И он выполнит обратный вызов в main.c timeout_cb () по истечении времени. Я также запускаю это в отдельном потоке, так как я не хочу блокировать в основном, так как у меня будет другой код, который мне нужно запустить.
1) Секунды в g_start_timer всегда дают хлам. Я думал, что смог бы решить эту проблему, создав структуру в куче. Есть ли способ решить эту проблему. Я думал о создании секундного элемента в куче. Но думаю, что все кончено, убить
2) Эта программа работает нормально, но если я закомментирую строку в main printf ("=== timeout_cb:% p \ n", timeout_cb); он будет складывать дамп.
3) когда лучше всего освобождать память. Я его в основном освобождал. Но меня беспокоит, будет ли память освобождена до завершения потока. Это могло вызвать очень неожиданный результат. Я думаю, что могу использовать thread_join () для освобождения памяти после этого вызова. Однако мне нужно будет вернуть thead_id, созданный в stop_watch.c, есть ли способ вернуть thread_id, созданный в stop_watch.c
Большое спасибо за любые предложения,
main.c
/* main.c */
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include "stop_watch.h"
/* call this when the time expires */
void timeout_cb()
{
printf("=== your time is up run some job here ===\n");
}
int main()
{
struct data_struct *g_data_struct =
(struct data_struct*) calloc(1, sizeof(*g_data_struct));
if(!g_data_struct)
{
printf("=== failed to allocate memory ===\n");
return 0;
}
g_data_struct->seconds = 3;
g_data_struct->func_ptr = timeout_cb;
// printf("=== timeout_cb: %p\n", timeout_cb);
start_stopwatch(g_data_struct);
// free(g_data_struct);
printf("=== End of Program - all threads in ===\n");
pthread_exit(NULL);
return 0;
}
stop_watch.h
/* stop_watch.h */
struct data_struct
{
int seconds;
void (*func_ptr)(void);
};
void start_stopwatch(struct data_struct *g_data_struct);
stop_watch.c
#include <stdio.h>
#include <pthread.h>
#include "stop_watch.h"
static void* g_start_timer(void *args)
{
void (*function_pointer)();
int seconds = ((struct data_struct*) args)->seconds;
function_pointer = ((struct data_struct*) args)->func_ptr;
printf("=== go to sleep for %d\n", seconds);
sleep(seconds);
(void) (*function_pointer)();
pthread_exit(NULL);
return 0;
}
void start_stopwatch(struct data_struct *g_data_struct)
{
pthread_t thread_id;
int rc;
int seconds = g_data_struct->seconds;
printf("=== start_stopwatch(): %d\n", seconds);
rc = pthread_create(&thread_id, NULL, g_start_timer, (void *) &g_data_struct);
if(rc)
printf("=== Failed to create thread\n");
}
Ответов (1)1
Строка в start_stopwatch()
:
rc = pthread_create(&thread_id, NULL, g_start_timer, (void *) &g_data_struct);
должно быть:
rc = pthread_create(&thread_id, NULL, g_start_timer, (void *) g_data_struct);
В первом случае вы передаете «указатель на указатель», когда действительно хотите передать указатель в качестве аргумента потока.
Что касается того, когда освобождать данные, существует множество вариантов. Если вы всегда будете передавать данные потока в блоке, выделенном в куче, то процесс g_start_timer()
потока может освободить его, когда закончит извлечение данных. Обратите внимание, что если вы это сделаете, то часть протокола для запуска потока состоит в том, что блок аргументов потока должен быть выделен в куче.