1:添加信号

  1.1 原型:sloop_handle sloop_register_signal(int sig, sloop_signal_handler handler, void * param)

 /* register a signal handler */
sloop_handle sloop_register_signal(int sig, sloop_signal_handler handler, void * param)
{
struct sloop_signal * entry;
struct sigaction sa; sa.sa_handler = sloop_signals_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART; /* allocate a new structure sloop_signal */
entry = get_signal();
if (entry == NULL)
return NULL; /* setup structure and insert into list. */
entry->sig = sig;
entry->param = param;
entry->handler = handler;
dlist_add(&entry->list, &sloop.signals);
SLOOPDBG(d_dbg("sloop: sloop_register_signal(%d)\n", sig));
if (sigaction(sig, &sa, NULL) < ) {
dlist_del(&entry->list);
free_signal(entry);
d_error("sigaction %d error %s\n", sig, strerror(errno));
return NULL;
} return entry;
}

  这个函数提供给使用sloop模块的第三方,只需要传入要监听的信号、信号处理函数、参数,就可以将此信号登记到sloop_data结构体中的struct dlist_head signals链表中,在sloop_run函数中进行监听。get_signal函数是从初始化时的struct dlist_head free_signals链表中取出一个可用的节点挂在struct dlist_head signals链表中。具体实现如下:

 /* get signal from pool */
static struct sloop_signal * get_signal(void)
{
struct dlist_head * entry;
struct sloop_signal * target; if (dlist_empty(&sloop.free_signals)) {
d_error("sloop: no sloop_signal available !!!\n");
return NULL;
}
entry = sloop.free_signals.next;
dlist_del(entry);
target = dlist_entry(entry, struct sloop_signal, list);
target->flags = SLOOP_INUSED | SLOOP_TYPE_SIGNAL;
return target;
}

  flags参数主要是为了标识此节点的类型,有三种类型,SLOOP_TYPE_SOCKETSLOOP_TYPE_TIMEOUTSLOOP_TYPE_SIGNAL

  1.2 一般使用方法

      sloop_register_signal(SIGTERM, sig_term,    NULL);登记SIGTERM信号的处理函数是sig_term,没有要传递的参数。

2:添加定时器

  2.1 原型:sloop_handle sloop_register_timeout(unsigned int secs, unsigned int usecs, sloop_timeout_handler handler, void * param)

  同添加信号的实现思路是一样的,需要传递的参数是定时器的秒和微妙参数。

 /* register a timer  */
sloop_handle sloop_register_timeout(unsigned int secs, unsigned int usecs, sloop_timeout_handler handler, void * param)
{
struct sloop_timeout * timeout, * tmp;
struct dlist_head * entry; /* allocate a new struct sloop_timeout. */
timeout = get_timeout();
if (timeout == NULL) return NULL; /* get current time */
gettimeofday(&timeout->time, NULL);
timeout->time.tv_sec += secs;
timeout->time.tv_usec += usecs; while (timeout->time.tv_usec >= ) {
timeout->time.tv_sec++;
timeout->time.tv_usec -= ;
}
timeout->handler = handler;
timeout->param = param;
INIT_DLIST_HEAD(&timeout->list); /* put into the list */
if (dlist_empty(&sloop.timeout)) {
dlist_add(&timeout->list, &sloop.timeout);
SLOOPDBG(d_dbg("sloop: timeout(0x%x) added !\n", timeout));
return timeout;
} entry = sloop.timeout.next;
while (entry != &sloop.timeout) {
tmp = dlist_entry(entry, struct sloop_timeout, list);
if (timercmp(&timeout->time, &tmp->time, < )) break;
entry = entry->next;
}
dlist_add_tail(&timeout->list, entry);
SLOOPDBG(d_dbg("sloop: timeout(0x%x) added !!\n", timeout));
return timeout;
}

  2.2 一般使用方法

  sloop_register_timeout(1, 0, wan_handler, param);在登记之后的1秒执行函数wan_handler。

3:添加套接字

  3.1 原型:套接字分为监听可读或可写两种

/* register a read socket */
sloop_handle sloop_register_read_sock(int sock, sloop_socket_handler handler, void * param)
{
return register_socket(sock, handler, param, &sloop.readers);
} /* register a write socket */
sloop_handle sloop_register_write_sock(int sock, sloop_socket_handler handler, void * param)
{
return register_socket(sock, handler, param, &sloop.writers);
}

   分别挂载到sloop.readers和sloop.writers链表上。

 static struct sloop_socket * register_socket(int sock,
sloop_socket_handler handler, void * param, struct dlist_head * head)
{
struct sloop_socket * entry; /* allocate a new structure sloop_socket */
entry = get_socket();
if (entry == NULL) return NULL; /* setup structure and insert into list. */
entry->sock = sock;
entry->param = param;
entry->handler = handler;
dlist_add(&entry->list, head);
SLOOPDBG(d_dbg("sloop: new socket : 0x%x (fd=%d)\n", (unsigned int)entry, entry->sock));
return entry;
}

  get_socket实现:

 /* get socket from pool */
static struct sloop_socket * get_socket(void)
{
struct dlist_head * entry;
struct sloop_socket * target; if (dlist_empty(&sloop.free_sockets)) {
d_error("sloop: no sloop_socket available !!!\n");
return NULL;
}
entry = sloop.free_sockets.next;
SLOOPDBG(daig_printf("%s: get socket sd=[%x],\n", __FILE__, entry));
dlist_del(entry);
target = dlist_entry(entry, struct sloop_socket, list);
target->flags = SLOOP_INUSED | SLOOP_TYPE_SOCKET;
return target;
}

综上:

  这就是这四种功能的实现思路及使用方式。

sloop公共函数之添加信号,定时器及socket的更多相关文章

  1. sloop公共程序之初始过程及启动

    1:sloop_init() 初始化主要是初始化静态sloop_*** 结构体和填充struct sloop_data 结构体中的成员. //初始化静态存储区给sloop_***结构体 static ...

  2. 除了信号触发线程与接收者线程相同的情况能直接调用到slot,其它情况都依赖事件机制(解决上面代码收不到信号的问题其实很简单,在线程的run();函数中添加一个事件循环就可以了,即加入一句exec();),信号槽不就是一个回调函数嘛

    MainWindow::MainWindow(QWidget *parent) :   QMainWindow(parent)   {   pThreadCon = new CSerialThread ...

  3. sloop公共程序之总体描述

    1:功能需求 开发一个公共库文件sloop.c,实现三个常用功能以供其它模块调用.三个功能如下: 功能一:实现一般的信号监听,调用模块只需传入要监听的信号和相应的回调函数就可以在信号到时调用回调函数处 ...

  4. 在Qt Creator 和在 vs2012 里添加信号和槽

    原文地址:http://www.cnblogs.com/li-peng/p/3644812.html 作者:李鹏 出处:http://www.cnblogs.com/li-peng/ 本文版权归作者和 ...

  5. Postman高级应用——流程控制、调试、公共函数、外部数据文件

    postman客户端下载地址:https://www.getpostman.com/apps 目录 流程控制 调试 公共函数 外部数据文件 流程控制 流程控制简言之就是设置接口的执行顺序,流程控制只有 ...

  6. VS2005 添加onTimer定时器

    SetTimer(1,300,NULL); void CchangeDisplayDlg::OnTimer(UINT_PTR nIDEvent) { // TODO: 在此添加消息处理程序代码和/或调 ...

  7. phpcms公共函数库 总结

    *  global.func.php 公共函数库 /** * 返回经addslashes处理过的字符串或数组 * @param $string 需要处理的字符串或数组 * @return mixed ...

  8. cmf公共函数解析

    cmf公共函数解析-common.php 路径:thinkcmf\simplewind\cmf\common.php方法: 方法 作用 返回值 cmf_get_current_admin_id    ...

  9. ThinkPHP 3.2.3 自动加载公共函数文件的方法

    方法一.加载默认的公共函数文件 在 ThinkPHP 3.2.3 中,默认的公共函数文件位于公共模块 ./Application/Common 下,访问所有的模块之前都会首先加载公共模块下面的配置文件 ...

随机推荐

  1. zabbix监控历史数据清理

    2018/12/24 14:00:57  zabbix监控运行一段时间以后,会留下大量的历史监控数据,zabbix数据库一直在增大:可能会造成系统性能下降,查看历史数据室查询速度缓慢. zabbix里 ...

  2. redis利用key计时与计数

    计时 Setex 命令为指定的 key 设置值及其过期时间.如果 key 已经存在, SETEX 命令将会替换旧的值 基本命令: redis 127.0.0.1:6379> SETEX KEY_ ...

  3. Yii2 yii\helpers\ArrayHelper

    yii\helpers\ArrayHelper 是一个数组辅助类,提供额外的数组功能函数 toArray($object, $properties = [], $recursive = true) C ...

  4. hihocoder #1032 : 最长回文子串 Manacher算法

    题目链接: https://hihocoder.com/problemset/problem/1032?sid=868170 最长回文子串 时间限制:1000ms内存限制:64MB 问题描述 小Hi和 ...

  5. TCP系列48—拥塞控制—11、FRTO拥塞撤销

    一.概述 FRTO虚假超时重传检测我们之前重传章节的文章已经介绍过了,这里不再重复介绍,针对后面的示例在说明两点 1.FRTO只能用于虚假超时重传的探测,不能用于虚假快速重传的探测. 2.延迟ER重传 ...

  6. selenium Object Page 设计模式理解及实现!

    Page Object模式是Selenium中的一种测试设计模式,主要是将每一个页面设计为一个Class,其中包含页面中需要测试的元素(按钮,输入框,标题 等),这样在Selenium测试页面中可以通 ...

  7. 新手必备!11个强大的 Visual Studio 调试技巧

    简介 调试是软件开发周期中很重要的一部分.它具有挑战性,同时也很让人疑惑和烦恼.总的来说,对于稍大一点的程序,调试是不可避免的.最近几年,调试工具的发展让很多调试任务变的越来越简单和省时. 这篇文章总 ...

  8. php奇葩错误:htmlspecialchars处理中文丢失

    $value = "中文中文"; $res = htmlspecialchars($value); 经过这个函数处理之后,$res就直接变成了空的字符串. 奇葩错误啊!后来发现要这 ...

  9. tooltips & click copy

    tooltips & click copy shit antd & tooltips & click copy https://codesandbox.io/s/zx4wo7y ...

  10. yarn add & yarn global add

    yarn global add & add -D https://yarnpkg.com/zh-Hans/docs/cli/add#toc-commands $ yarn global add ...