callback and notify

回调函数是什么?

回调函数或简称回调(callback),是计算机编程中对某一段可执行代码的引用,它被作为参数传递给另一段代码;预期这段代码将回调(执行)这个回调函数作为自己工作的一部分。这种执行可以是即时的,如在同步回调之中;也可以在后来的时间点上发生,如在异步回调之中。

在C语言中通过函数指针实现回调函数,其中回调函数的典型例子就是信号处理 :

1
void (*signal(int sig, void (*func)(int)))(int);

示例1:基于回调函数的信号捕捉实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>

bool g_main_loop = true;

void signal_handler(int signum)
{
switch (signum)
{
case SIGINT: // 接收到该信号后,退出程序
printf("SIGINT: %d\n", signum);
g_main_loop = false;
break;
case SIGUSR1:
printf("SIGUER1: %d\n", signum);
break;
case SIGUSR2:
printf("SIGUER2: %d\n", signum);
break;
case SIGTERM:
printf("SIGTERM: %d\n", signum);
break;
default:
break;
}
}

int main()
{
signal(SIGINT, signal_handler);

while(g_main_loop)
{
sleep(1);
}

return(0);
}

示例2:当A发布了任务给B,B执行任务,若任务有进度变化B立即告知A。当然A并不会一直顶着A的任务进度变化,A发布任务后,就去干其他活了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdbool.h>
#include <pthread.h>
#include <signal.h>

// 定义回调函数类型
typedef void (*CallbackFunction)(int new_value);

// 数据处理器结构体
typedef struct {
int x;
CallbackFunction callback;
} DataHandler;

bool g_main_loop = true;

// 数据处理器改变x值的方法
void change_value(DataHandler *handler, int new_value)
{
handler->x = new_value;
// 如果存在回调函数,则调用它
if (handler->callback != NULL)
{
handler->callback(new_value);
}
}

// 回调函数定义
void notify_callback(int new_value)
{
printf("Callback triggered: new value of x is %d\n", new_value);
}

// 线程A的工作函数
void *thread_function(void *arg)
{
DataHandler *handler = (DataHandler *) arg;
int value = 0;
while (1)
{
change_value(handler, value++); // 改变x的值并触发回调
sleep(2);
}
return NULL;
}

// 数据处理器的初始化函数
DataHandler handler;
int data_handler_register(CallbackFunction cb)
{
pthread_t tid;
handler.x = 0;
handler.callback = cb;

if (pthread_create(&tid, NULL, thread_function, &handler) != 0)
{
fprintf(stderr, "Failed to create thread.\n");
return -1;
}
pthread_detach(tid);

return 0;
}

void signal_handler(int signum)
{
switch (signum)
{
case SIGINT: // 接收到该信号后,退出程序
printf("SIGINT: %d\n", signum);
g_main_loop = false;
break;
case SIGUSR1:
printf("SIGUER1: %d\n", signum);
break;
case SIGUSR2:
printf("SIGUER2: %d\n", signum);
break;
case SIGTERM:
printf("SIGTERM: %d\n", signum);
break;
default:
break;
}
}

int main(void)
{
signal(SIGINT, signal_handler);

// 初始化数据处理器并设置回调函数
if (0 != data_handler_register(notify_callback))
{
return -1;
}
while (g_main_loop)
{
sleep(1);
}

printf("exit\n");

return 0;
}

其中main线程称之为A,设置和定义了回调函数notify_callback(),回调函数赋值给了handler的cb成员。在mian线程中创建了thread_function线程,称之为B,handler作为参数给到了B(即A发布了任务到B),B每隔2秒调用回调函数(即通知A任务进度变化)。

参考来源

1、回调函数