首页 > 其他分享 >c定时执行任务

c定时执行任务

时间:2023-05-03 22:57:08浏览次数:45  
标签:NULL signal sighandler worker 任务 线程 pthread 定时 执行

由一个C定时执行任务的程序引发的思考

程序

这里使用C写了个定时执行的程序,见a.c

//a.c
#include <stdio.h>
#include <pthread.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>

void* send_signal_every_second(void* args) {
  while(1) {
    kill(getpid(), SIGALRM);
    sleep(1);
  }
}

void sighandler(int);
void *print_hello_when_receive_signal(void* args) {
  signal(SIGALRM, sighandler); 
  while(1) {} // exec sighandler every one seconds, signal will interrupt this while in worker thread.
}

void sighandler(int signum) {
  printf("Get signal %ld\n", time(NULL));
}

int main() {
  pthread_t timer;
  pthread_t worker;
  int res2 = pthread_create(&worker, NULL, print_hello_when_receive_signal, NULL);
  if(res2) {
    printf("Error in create thread print_hello_when_receive_signal \n");
    exit(0);
  }
  int res = pthread_create(&timer, NULL, send_signal_every_second, NULL);
  if(res) {
    printf("Error in create thread send_signal_every_second \n");
    exit(0);
  }

  pthread_join(worker, NULL);
  pthread_join(timer, NULL);
}

Makefile

a.out: a.c
	gcc a.c -lpthread

除了主线程之外,设计了两个线程。其中一个叫timer,另外一个叫worker。

timer线程工作入口函数为send_signal_every_second,负责定时发送信号,程序中通过sleep函数,每隔1s发送SIGALRM信号给当前进程(getpid())。

worker线程工作的入口函数为print_hello_when_receive_signal,进入之后,首先为进程的SIGALRM信号设置了一个sighandler处理函数,然后进入一个循环。

执行的时候,就能看到终端上,每隔1s打印一行信息。

对代码进行复盘

  1. 进程收到signal,是另外开辟一个线程来执行吗sighandler吗?还是在当前线程?

当前代码的进程会产生三个线程:主线程,worker和timer线程。主线程在main函数的最后等另外两个线程。对于第一个问题,sighandler不会开新线程来跑,而是在现有的线程中随机运行,甚至可能在主线程上执行。参考https://zhuanlan.zhihu.com/p/460255685。worker的死循环可以不用,然worker线程很快得自然结束,sighander在主线程或timer线程上同样会被每隔1s调用一次。

如何在linux下看某进程的线程?ls -l /proc/pid/task。可以看到每个线程一个编号。

  1. pthread_join之后,主线程是什么状态?
    首先可以明确pthread_join函数是非阻塞的。执行完,主线程在等到待join线程结束之前不会结束。主线程中是什么状态待定(TODO).

  2. 某线程通过sleep函数睡眠的时候,能被signal唤醒吗?
    通过nanosleep函数(对应到了系统调用)的manual说明,是可以唤醒的。这个从常识中也可以得到这个结论:当某个进程sleep或等待输入的时候,也是可以通过ctrl+c将其终止的。

nanosleep() suspends the execution of the calling thread until either at least the time specified in *req has elapsed, or the delivery of a signal that triggers the invocation of a handler in the calling thread or that terminates the process.
If the call is interrupted by a signal handler, nanosleep() returns -1, sets errno to EINTR, and writes the remaining time into structure pointed by rem unless rem is NULL. The value of *rem can then be used to call nanosleep() again and complete the specified pause (but see notes).

从字面意思上看,nanosleep的时间控制可以到$10^{-9}$。若某个进程sigHandler打断了nanosleep,并很busy,一直在一个for循环里,且没有使用类似sleep/read/write的系统调用(单纯的ALU计算),则for中切入signal中断的机会在tick进程切换过程中,所以时间可能会比真实发送信号的时间多大概一个tick的时间。

https://superuser.com/questions/101183/what-is-a-cpu-tick, https://learn.microsoft.com/en-us/dotnet/api/system.datetime.ticks?redirectedfrom=MSDN&view=net-7.0#System_DateTime_Ticks可以看到,windows和linux两个tick直接相差的时间设置的都是100ns, 即10000个tick每毫秒。每个tick会引起操作系统切换一次进程。可以看到测试。

  1. 若nanosleep被打断了,执行静默的thread是不是就立即静默,并进入到下一条指令的执行?
    通过测试,观察到,被外部signal打断即退出sleep状态了。

标签:NULL,signal,sighandler,worker,任务,线程,pthread,定时,执行
From: https://www.cnblogs.com/zwlwf/p/17369845.html

相关文章

  • 2023-05-03:给你一棵 二叉树 的根节点 root ,树中有 n 个节点 每个节点都可以被分配一个
    2023-05-03:给你一棵二叉树的根节点root,树中有n个节点每个节点都可以被分配一个从1到n且互不相同的值另给你一个长度为m的数组queries你必须在树上执行m个独立的查询,其中第i个查询你需要执行以下操作:从树中移除以queries[i]的值作为根节点的子树题目所用测试......
  • 2023-05-03:给你一棵 二叉树 的根节点 root ,树中有 n 个节点 每个节点都可以被分配一个
    2023-05-03:给你一棵二叉树的根节点root,树中有n个节点每个节点都可以被分配一个从1到n且互不相同的值另给你一个长度为m的数组queries你必须在树上执行m个独立的查询,其中第i个查询你需要执行以下操作:从树中移除以queries[i]的值作为根节点的子树题目所......
  • 关于pandas.ExcelWriter()对象在执行.save()时报错FutureWarning: save is not part o
    有时使用pandas将多份数据,写入到Excel中不同的Sheet,可能会用到pandas.ExcelWriter("xxxx.xlsx")对象这样在结束时,就会对对象进行.save()和close(),当然这也是从大部分网站上看到的使用方法但是笔者在实际使用过程中,按这个过程,遇到报错:FutureWarning:saveisnotpartofthepu......
  • [MAUI]模仿iOS多任务切换卡片滑动的交互实现
    @目录原理创建布局创建分布函数创建动效创建绑定数据细节调整首张卡片的处理为卡片添加裁剪跳转到最后一张卡片项目地址看了上一篇博文的评论,大家对MAUI还是比较感兴趣的,非常感谢大家的关注,这个专栏我争取周更......
  • 七、使用调度框架quartz,为12306系统增加定时调度功能
    为什么要有定时调度定时调度在企业级系统中非常重要(统计报表、功能补偿、不紧急的大批量任务)12306每天都需要生成15天后的车次数据本章内容集成quartz,比较SpringBoot自带定时任务喝quartz的区别使用控台来操作定时任务:新增、暂停、重启、删除项目中增加batch定时调度......
  • tornado服务端+tornado.ioloop.PeriodicCallback定时任务踩坑记录及解决方案
    背景:用tornado部署一个AI模型的服务端,由于AI模型较慢,收到请求肯定没办法同步返回结果,所以最后定的方案是批处理并异步回调。异步回调下,我这边的处理方式是:实时接收所有请求并多线程落库(使用数据库连接池),再启动一个定时任务取出库中(未处理过的)数据进行批处理。因为web框架用的是tor......
  • 简单总结JavaScript中的微任务和宏任务
    在JavaScript中,任务被分为宏任务和微任务。宏任务:常见的宏任务有setTimeout、setInterval、I/O、UI渲染等等。这些任务都是由浏览器或Node.js中的事件循环调度执行的,它们会被放入一个任务队列(taskqueue)中,等待执行。微任务:常见的微任务有Promise、MutationObserver等。......
  • pytest的几种执行方式
    1pytestxxxx2python-mpytestxxxxpython-mpytest--html=./report/rep2.htmltest_env_pytest_ini.py这个与pytest几乎是相同的,官网是这样说的3pythonpytestxxx这与python-mxxx很像,对于pytest执行结果来说没有区别,python-mxx如上截图所说,它会将当前工作目录......
  • struts2 s2-062 ONGL远程代码执行
    struts2s2-062ONGL远程代码执行一、Struts2介绍struts2是一种重量级的框架,位于MVC架构中的controller,可以分析出来,它是用于接受页面信息然后通过内部处理,将结果返回。struts2也是一个web层的MVC框架。Java中SSH框架SSH为Struts+Spring+Hibernate的一个集成框架,是目前较流行......
  • 涵盖1600+任务的巨型Benchmark来了!跑个测试花一周??
    文|兔子酱最近,benchmanking又卷出了新高度,allenAI前段时间发布了史上最强基准测试——NATURAL-INSTRUCTIONSv2,涵盖了1600+个任务、70+个不同任务类型、50+种不同语言,用来测试生成模型的泛化性。论文标题:BenchmarkingGeneralizationviaIn-ContextInstructionson1,600+Lan......