OpenWRT | Uloop编程技术

API 介绍:

# fd 相关
int uloop_fd_add(struct uloop_fd *sock, unsigned int flags);
int uloop_fd_delete(struct uloop_fd *sock);

# 定时器相关
int uloop_timeout_add(struct uloop_timeout *timeout);
int uloop_timeout_set(struct uloop_timeout *timeout, int msecs);
int uloop_timeout_cancel(struct uloop_timeout *timeout);
int uloop_timeout_remaining(struct uloop_timeout *timeout) __attribute__((deprecated("use uloop_timeout_remaining64")));
int64_t uloop_timeout_remaining64(struct uloop_timeout *timeout);

# 进程相关
int uloop_process_add(struct uloop_process *p);
int uloop_process_delete(struct uloop_process *p);

# 控制uloop循环
bool uloop_cancelling(void);
static inline void uloop_end(void)
{
        uloop_cancelled = true;
}
int uloop_init(void);
int uloop_run_timeout(int timeout);
static inline int uloop_run(void)
{
        return uloop_run_timeout(-1);
}
void uloop_done(void);

DEMO

01_hello.c

#include <stdio.h>
#include <libubox/uloop.h>

int main()
{
    uloop_init();

    printf("hello world\n");
    uloop_run();
    uloop_done();
    return 0;
}

现象:

root@DataJar-0C7D:~# ./01_hello 
hello world

02_timer.c

#include <stdio.h>
#include <string.h>
#include <libubox/uloop.h>

// timeout 必须是全局的,或者静态的
// 一次性定时器
static struct uloop_timeout once_timer;
// 永久性定时器
static struct uloop_timeout forever_timer;

static struct uloop_timeout limit_cnt_timer;
static int cnt = 10;

static void once_timer_callback(struct uloop_timeout *timeout)
{
    printf("once_timer_callback\n"); 
}

static void forever_timer_callback(struct uloop_timeout *timeout)
{
    printf("forever_timer_callback\n");
    uloop_timeout_set(timeout, 1000);
}

static void forever2_timer_callback(struct uloop_timeout *timeout)
{
    static struct uloop_timeout forever_timer2 = {
        .cb = forever2_timer_callback
    };
    printf("forever2_timer_callback\n");
    uloop_timeout_set(&forever_timer2, 1000);
}

static void limit_cnt_timer_callback(struct uloop_timeout *timeout)
{
    printf("limit_cnt_timer_callback: %d\n", cnt); 

    if (cnt > 0) {
        uloop_timeout_set(&limit_cnt_timer, 1000);
        cnt--;
    }
}

static void example1()
{
    memset(&once_timer, 0, sizeof(struct uloop_timeout));
    once_timer.cb = once_timer_callback;
    uloop_timeout_set(&once_timer, 1000);
}

static void example2()
{
    memset(&forever_timer, 0, sizeof(struct uloop_timeout));
    forever_timer.cb = forever_timer_callback;
    uloop_timeout_set(&forever_timer, 1000);
}

static void example3()
{
    forever2_timer_callback(NULL);
}

static void example4()
{
    memset(&limit_cnt_timer, 0, sizeof(struct uloop_timeout));
    limit_cnt_timer.cb = limit_cnt_timer_callback;
    uloop_timeout_set(&limit_cnt_timer, 1000);
}

int main(int argc, char **argv)
{
    uloop_init();

    if (argc > 1) {
        if (strcmp(argv[1], "1") == 0) {
            example1();
        } else if (strcmp(argv[1], "2") == 0) {
            example2();
        } else if (strcmp(argv[1], "3") == 0) {
            example3();
        } else if (strcmp(argv[1], "4") == 0) {
            example4();
        }
    } else {
        example1();
    }

    uloop_run();
    uloop_done();
    return 0;
}

现象:

root@DataJar-0C7D:~# ./02_timer 1
once_timer_callback
root@DataJar-0C7D:~# ./02_timer 2
forever_timer_callback
forever_timer_callback
forever_timer_callback
root@DataJar-0C7D:~# ./02_timer 3
forever2_timer_callback
forever2_timer_callback
forever2_timer_callback
root@DataJar-0C7D:~# ./02_timer 4
limit_cnt_timer_callback: 10
limit_cnt_timer_callback: 9
limit_cnt_timer_callback: 8
limit_cnt_timer_callback: 7
limit_cnt_timer_callback: 6
limit_cnt_timer_callback: 5
limit_cnt_timer_callback: 4
limit_cnt_timer_callback: 3
limit_cnt_timer_callback: 2
limit_cnt_timer_callback: 1
limit_cnt_timer_callback: 0

03_fd.c

#include <stdio.h>
#include <libubox/uloop.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

static struct uloop_fd sock;

void sock_read_handler(struct uloop_fd *u, unsigned int events)
{
    printf("sock_read_handler\n");
}

void example1()
{
    memset(&sock, 0, sizeof(struct uloop_fd));

    // 读取 /proc/kmsg
    int fd = open("/proc/kmsg", S_IREAD);
    if (fd < 0) {
        perror("open");
        return;
    }
    sock.fd = fd;
    sock.cb = sock_read_handler;

    uloop_fd_add(&sock, ULOOP_READ);
}

int main()
{
    uloop_init();

    example1();

    uloop_run();
    uloop_done();
    return 0;
}

现象:

root@DataJar-0C7D:~# echo 111 > /dev/kmsg
[ 4531.381035] 111
root@DataJar-0C7D:~# sock_read_handler
sock_read_handler
sock_read_handler
sock_read_handler
sock_read_handler

root@DataJar-0C7D:~# echo 111 > /dev/kmsg
[ 4535.670722] 111
root@DataJar-0C7D:~# sock_read_handler

04_process.c

#include <stdio.h>
#include <libubox/uloop.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

static struct uloop_process proc;

void process_cb(struct uloop_process *c, int ret)
{
    // 判断是否是通过exit退出,而不是信号
    if (WIFEXITED(ret)) {
        printf("child process exit with: %d\n", WEXITSTATUS(ret));
    }
}


int main()
{
    uloop_init();

    memset(&proc, 0, sizeof(struct uloop_process));

    pid_t pid = fork();
    if (pid == 0) {
        // 返回127退出
        exit(127);

    } else {
        proc.pid = pid;
        proc.cb = process_cb;
        uloop_process_add(&proc);
    }
    
    uloop_run();
    uloop_done();
    return 0;
}

现象:

root@DataJar-0C7D:~# ./04_process 
child process exit with: 127

注意点:

  • 模板:

    uloop_init();
    xxxx
    uloop_run(); // 阻塞
    uloop_free();
    
  • uloop 监听文件描述符时,flags 常用有两个取值:ULOOP_READ,ULOOP_WRITE

  • uloop_timeout_add 与 uloop_timeout_set 功能类似,使用需确保 uloop_timeout 提前设置了超时时间

  • 不支持多线程 uloop,因为 uloop 使用了全局变量来共享数据

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值