softlockup detector

1 简介

从内核稳定性问题的角度来看内核安全,是基础,也是必备技能。很多时候,一个内核稳定性问题,就是造成系统安全的罪魁祸首。

当出现异常死锁、Hang up、死机等问题时,watchdog的作用就很好的体现出来。Watchdog主要用于监测系统运行情况,一旦出现以上异常情况,就会重启系统,并收集crash dump(程序崩溃时保存的运行数据)。

watchdog包括硬件watchdog和软件实现的watchdog,前者是硬件模块,触发时直接硬件复位CPU重启,无法收集crash dump。而软件实现的watchdog可触发panic,收集crashdump等, 软件watchdog在Linux内核中有softlockup detector和hardlockup detector,安卓framework也有watchdog。

本文介绍softlockup detector

2 工作原理

  1. 假定某一变量的状态能表征系统运行状态,比如中断次数(如果高优先级中断没有发生,就认为CPU卡死),比如/dev/watchdog时间戳(如果超时时间到了仍没有向watchdog节点写数据,就认为用户空间卡死)。
  2. 启动一个watchdog程序,定期观测该变量,来判定系统是否正常,并采取相应动作。
  3. 内核态watchdog主要用于检测内核Lockup。所谓的Lockup,是指某段内核代码一直占着CPU不放,此时内核调度器无法进行调度工作。进一步严重情况下,会导致整个系统卡死。
  4. Lockup涉及到内核线程、时钟中断。它们有不一样的优先级:内核线程 < 时钟中断 。其中,内核线程可以被调度或被中断打断。

3 Lockup分类

  • 只有内核代码才能引起lockup,因为用户代码是可以被抢占的,只有一种情况例外,就是SCHED_FIFO( 一直运行,直到进程运行完毕才会释放CPU)优先级为99的实时进程。当它被阻塞或被更高优先级进程抢占时,也可能使[watchdog/x]内核线程抢不到CPU而形成soft lockup。
  • 内核代码必须处于禁止内核抢占的状态(preemption disabled),Linux是可抢占的,只在某些特定的代码区才禁止抢占(例如spinlock),才可能形成lockup。

Lockup 分为两种:soft lockup 和 hard lockup

  • Soft lockup在CPU无法正常调度其他线程时发生,即某段代码一直占用某个CPU,导致watchdog/x内核线程得不到调度,此时中断仍可响应;
  • Hard lockup在中断无法正常响应时发生,即关中断时间过长或中断处理程序执行时间过长。

4 softlockup detector 详解

在驱动中加入以下代码可触发soft lockup,通过spinlock()实现关抢占,使得该CPU上的[watchdog/x]线程无法被调度。

static spinlock_t spinlock;
spin_lock_init(&spinlock);
spin_lock(&spinlock);
while(1);
  • soft lockup detector机制通过smp_hotplug_thread机制为每个CPU核创建一个内核线程[watchdog/X] (其中N为CPU ID,该内核线程为FIFI 99最高优先级,此类线程设置了 p->flags |= PF_NO_SETAFFINITY属性,不允许用户空间设置CPU亲和性)。该线程定时(每隔4s执行一次)对变量watchdog_touch_ts加加操作,即喂狗。
  • 然后给每个CPU分配一个高精度hrtimer([watchdog/X] 首次执行时就被创建),该定时器的中断服务程序会每隔4s(sample_period seconds (4 seconds by default))检测一下变量watchdog_touch_ts是否被更新过,如果20s内该变量仍未更新,就说明CPU卡住,导致watchdog线程无法调度。

hrtimer的中断处理函数是:kernel/watchdog.c/watchdog_timer_fn()。

中断处理函数主要做了以下事情:

  1. 对变量hrtimer_interrupts加加操作,该变量同时供hard lockup detector用于判断CPU是否响应中断。
  2. 唤醒[watchdog/x]内核线程喂狗(执行soft_lockup_hrtimer_cnt=hrtimer_interrupts赋值即将hrtimer_interrupts更新到soft_lockup_hrtimer_cnt,同时更新watchdog_touch_ts到当时系统时间截,下图有误,并非++)。
  3. 检测变量watchdog_touch_ts是否被更新,如果超过20s未更新,说明[watchdog/x]未得到运行,发生了soft lockup,CPU被霸占。

注意:这里的内核线程[watchdog/x]的目的是操作变量watchdog_touch_ts,该变量是被watch的对象。而真正的看门狗,则是由hrtimer中断触发的,即 watchdog_timer_fn()函数,该函数会唤醒喂狗线程。[watchdog/x]是被scheduler调度执行的,而watchdog_timer_fn()则是被中断触发的。

img

5 源码分析

5.1 全局变量与数据结构

/* Global variables, exported for sysctl */
unsigned int __read_mostly softlockup_panic =CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE;static bool softlockup_threads_initialized __read_mostly;
static u64 __read_mostly sample_period; //定时器时间周期,默认4秒//以下per cpu变量,每个CPU有一个
static DEFINE_PER_CPU(unsigned long, watchdog_touch_ts); //[watchdog/x]线程更新的时间截
static DEFINE_PER_CPU(struct task_struct *, softlockup_watchdog);//[watchdog/x]线程的 task_struct结构指针
static DEFINE_PER_CPU(struct hrtimer, watchdog_hrtimer);//[watchdog/x]线程对应的hrtimer中断定时器控制结构
static DEFINE_PER_CPU(bool, softlockup_touch_sync);
static DEFINE_PER_CPU(bool, soft_watchdog_warn);//发生softlockup当标记为true,否则false
static DEFINE_PER_CPU(unsigned long, hrtimer_interrupts);//hrtimer定时器watchdog_timer_fn自增
static DEFINE_PER_CPU(unsigned long, soft_lockup_hrtimer_cnt);//[watchdog/x]线程更新soft_lockup_hrtimer_cnt=hrtimer_interrupts
static DEFINE_PER_CPU(struct task_struct *, softlockup_task_ptr_saved);//定时器回调watchdog_timer_fn保存发生softlockup时current,它不是[watchdog/x]线程的 task_struct结构指针
static DEFINE_PER_CPU(unsigned long, hrtimer_interrupts_saved);//用在hardlockup dectector中
static unsigned long soft_lockup_nmi_warn;static struct smp_hotplug_thread watchdog_threads = {.store			= &softlockup_watchdog,//[watchdog/x]线程的 task_struct结构指针,上面定义的per cpu变量.thread_should_run	= watchdog_should_run,//return (hrtimer_interrupts) !=soft_lockup_hrtimer_cnt),两者不等则返回true.thread_fn		= watchdog,//[watchdog/x]线程的喂狗回调,先会调用thread_should_run返回true则执行,否则不执行。.thread_comm		= "watchdog/%u",.setup			= watchdog_enable,//[watchdog/x]线程激活时被执行,比thread_fn(即喂狗)回调执行早,它会创建hrtimer,同时设置[watchdog/x]为FIFO 99.cleanup		= watchdog_cleanup,//内部调用下面的watchdog_disable,当有人对此kthread调用了 kthread_stop() 时被执行,一般是module_exit,softlockup的模块一般不会被调用.park			= watchdog_disable,//执行与[watchdog/x]相反的操作,取消定时器,[watchdog/x]线程设为CFS 优先级0.unpark			= watchdog_enable,
};

5.2 创建[watchdog/x]线程(per cpu thread)

softlockup detector通过smp_hotplug_thread机制创建per cpu thread。关于smp_hotplug_thread机制详细见《Linux内核机制smp_hotplug_thread》

kernel_init_freeablelockup_detector_init  //比do_basic_setup调用的早,因此比 early_initcall 调用的还早lockup_detector_setup:ret = smpboot_register_percpu_thread_cpumask(&watchdog_threads, &watchdog_allowed_mask);softlockup_threads_initialized = true;lockup_detector_reconfigure();//detector的配置初始化,包括定时器的周期参数等。/**  smpboot.c* smpboot_register_percpu_thread_cpumask - Register a per_cpu thread related to hotplug* @plug_thread:	Hotplug thread descriptor* @cpumask:		The cpumask where threads run** Creates and starts the threads on all online cpus.*/
int smpboot_register_percpu_thread_cpumask(struct smp_hotplug_thread *plug_thread, const struct cpumask *cpumask)
{unsigned int cpu;int ret = 0;
.................for_each_online_cpu(cpu) {__smpboot_create_thread(plug_thread, cpu);//创建per_cpu thread 即[watchdog/x]smpboot_unpark_thread(plug_thread, cpu);//unpark per_cpu thread}list_add(&plug_thread->list, &hotplug_threads);//挂到hotplug_threads中,以便core管理
............
}static int __smpboot_create_thread(struct smp_hotplug_thread *ht, unsigned int cpu)
{struct task_struct *tsk = *per_cpu_ptr(ht->store, cpu);struct smpboot_thread_data *td;td = kzalloc_node(sizeof(*td), GFP_KERNEL, cpu_to_node(cpu));td->cpu = cpu;td->ht = ht;tsk = kthread_create_on_cpu(smpboot_thread_fn, td, cpu,  ht->thread_comm);//创建per_cpu thread 即[watchdog/x]kthread_park(tsk);get_task_struct(tsk);*per_cpu_ptr(ht->store, cpu) = tsk;//内核线程的task_struct指针保存到上面定义的per cpu变量中return 0;
}static int smpboot_thread_fn(void *data)
{struct smpboot_thread_data *td = data;struct smp_hotplug_thread *ht = td->ht;while (1) {set_current_state(TASK_INTERRUPTIBLE);preempt_disable(); //关抢占............................/* Check for state change setup */switch (td->status) {case HP_THREAD_NONE:__set_current_state(TASK_RUNNING);preempt_enable();if (ht->setup) //调用setup即上面的watchdog_enable,,它会创建hrtimer,同时设置[watchdog/x]为FIFO 99ht->setup(td->cpu);td->status = HP_THREAD_ACTIVE;continue;case HP_THREAD_PARKED:__set_current_state(TASK_RUNNING);preempt_enable();if (ht->unpark)ht->unpark(td->cpu);td->status = HP_THREAD_ACTIVE;continue;}if (!ht->thread_should_run(td->cpu)) {//return (hrtimer_interrupts) !=soft_lockup_hrtimer_cnt),两者不等则返回truepreempt_enable_no_resched();schedule();} else {__set_current_state(TASK_RUNNING);preempt_enable();ht->thread_fn(td->cpu);//上面的(hrtimer_interrupts) !=soft_lockup_hrtimer_cnt),则执行thread_fn即喂狗函数watchdog()}}
}

5.3 创建hrtimer定时器

由上面的smp_hotplug_thread机制的smpboot_thread_fn处理可知,内核线程第一次执行smp_hotplug_thread::setup()回调时被调用,即watchdog_enable:

static void watchdog_enable(unsigned int cpu)
{struct hrtimer *hrtimer = this_cpu_ptr(&watchdog_hrtimer);/** Start the timer first to prevent the NMI watchdog triggering* before the timer has a chance to fire.*/hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);hrtimer->function = watchdog_timer_fn;hrtimer_start(hrtimer, ns_to_ktime(sample_period), HRTIMER_MODE_REL_PINNED);/* Initialize timestamp */__touch_watchdog();//喂一次狗,初始化watchdog_touch_ts值,因为上面定义时没初始化,它是0//smp_hotplug_thread机制创建的内核线程是CFS 120,此处设置为FIFO 99watchdog_set_prio(SCHED_FIFO, MAX_RT_PRIO - 1);
}

以上5.2, 5.3节流程处理完后,系统为每个CPU核创建了一个内核线程,优先级为FIFO 99:

sh-3.2# ps | grep watchdog12 root         0 SW   [watchdog/0]15 root         0 SW   [watchdog/1]21 root         0 SW   [watchdog/2]27 root         0 SW   [watchdog/3]
sh-3.2# chrt -p 12
pid 12's current scheduling policy: SCHED_FIFO
pid 12's current scheduling priority: 99

5.4 定时喂狗

5.4.1 hrtimer时间周期

在detector init中(5.2节也提到),配置了定时器的周期参数sample_period(全局变量),它的值由watchdog_thresh乘2除5,转化为纳秒计算得来,watchdog_thresh默认10秒(可通过/proc/sys/kernel/watchdog_thresh修改),即定时器一次调用周期4秒,即每4秒喂一狗,详见如下代码:

lockup_detector_initlockup_detector_setup:ret = smpboot_register_percpu_thread_cpumask(&watchdog_threads, &watchdog_allowed_mask);softlockup_threads_initialized = true;lockup_detector_reconfigure()://detector的配置初始化,包括定时器的周期参数等。set_sample_periodstatic int get_softlockup_thresh(void)
{return watchdog_thresh * 2;//watchdog_thresh默认是10秒, 可通过/proc/sys/kernel/watchdog_thresh修改
}
static void set_sample_period(void)
{sample_period = get_softlockup_thresh() * ((u64)NSEC_PER_SEC / 5);//20除5==4秒,转化为纳秒作为hrtimer采样周期。watchdog_update_hrtimer_threshold(sample_period);//hardlockup detector用的,不关心。
}
5.4.2 hrtimer定时器喂狗

主要做了两件事:

  • soft_lockup_hrtimer_cnt == hrtimer_interrupts
  • watchdog_touch_ts == get_timestamp(); //喂狗
//watchdog_timer_fn是5.3节创建hrtimer定时器时绑定的回调函数,每隔4秒执行一次:
static enum hrtimer_restart watchdog_timer_fn(struct hrtimer *hrtimer)
{unsigned long touch_ts = __this_cpu_read(watchdog_touch_ts);/* kick the softlockup detector *///唤醒内核线程[watchdog/x],它会通过thread_should_run判断是否应该调用thread_fn即喂狗函数watchdog,详见见smpboot_thread_fn//thread_should_run是return (hrtimer_interrupts) !=soft_lockup_hrtimer_cnt),两者不等则返回truewake_up_process(__this_cpu_read(softlockup_watchdog)); //唤醒[watchdog/X]线程喂狗/* .. and repeat */hrtimer_forward_now(hrtimer, ns_to_ktime(sample_period));//更新定时器,4秒后再触发。.....
}/*下面两个都是[watchdog/X]线程的上下文,正在喂狗的地方,上面是hrtimer定时器的上下文(主要用于唤醒唤醒[watchdog/X]线程及检测是否发生softlockup),发生softlockup时dumpstack栈空间是hrtimer的上下文,即发生softlockup时在CPU上running的线程。*/
static void __touch_watchdog(void)
{__this_cpu_write(watchdog_touch_ts, get_timestamp());//喂狗
}
static void watchdog(unsigned int cpu)
{__this_cpu_write(soft_lockup_hrtimer_cnt,  __this_cpu_read(hrtimer_interrupts));__touch_watchdog();//喂狗
}

5.5 hrtimer定时器detect softlockup

hrtimer每隔4秒检测是否发生softlockup,检测逻辑为:
如果20s内都没更新watchdog_touch_ts ,就认为出现了soft lockup,详细原理见2节和4节。

/* Global variables, exported for sysctl */
unsigned int __read_mostly softlockup_panic = CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE;/* watchdog_timer_fn是5.3节创建hrtimer定时器时绑定的回调函数,每隔4秒执行一次: */
static enum hrtimer_restart watchdog_timer_fn(struct hrtimer *hrtimer)
{unsigned long touch_ts = __this_cpu_read(watchdog_touch_ts);watchdog_interrupt_count();  /* 对hrtimer_interrupts加1操作*/wake_up_process(__this_cpu_read(softlockup_watchdog)); /* 唤醒喂狗线程[watchdog/X] 见5.4.2节*//* ..  and repeat  更新定时器,4秒后再触发。 */hrtimer_forward_now(hrtimer, ns_to_ktime(sample_period));/* check for a softlockup* This is done by making sure a high priority task is* being scheduled.  The task touches the watchdog to* indicate it is getting cpu time.  If it hasn't then* this is a good indication some task is hogging the cpu* 英文判断softlockup很详细,如果某个CPU卡死,该CPU的watchdog线程不会被调度,即watchdog_touch_ts* 不会被更新。如果20s内都没更新watchdog_touch_ts ,就认为出现了soft lockup* is_softlockup内部实现是:* 如果watchdog_touch_ts 20秒更新,返回duration = 当时时间截 - watchdog_touch_ts 否则返回0* duration > 0表示发生了softlockup*/duration = is_softlockup(touch_ts);if (unlikely(duration)) {pr_emerg("BUG: soft lockup - CPU#%d stuck for %us! [%s:%d]\n",smp_processor_id(), duration,current->comm, task_pid_nr(current));__this_cpu_write(softlockup_task_ptr_saved, current);print_modules();print_irqtrace_events(current);dump_stack();add_taint(TAINT_SOFTLOCKUP, LOCKDEP_STILL_OK);if (softlockup_panic) //CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE配置为1时触发softlockup panicpanic("softlockup: hung tasks");__this_cpu_write(soft_watchdog_warn, true);} else__this_cpu_write(soft_watchdog_warn, false);return HRTIMER_RESTART;
}static int is_softlockup(unsigned long touch_ts)
{unsigned long now = get_timestamp();/* 如果某个CPU卡死,该CPU的watchdog线程不会被调度,即watchdog_touch_ts *//* 不会被更新。如果20s内都没更新watchdog_touch_ts ,就认为出现了soft lockup *//* get_softlockup_thresh()函数返回20 */if (time_after(now, touch_ts + get_softlockup_thresh()))return now - touch_ts;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/737991.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

drduino串口通信中文乱码

​ 第一次使用 Arduino 板学习时,遇到了串口工具接收乱码的问题。 最初认为可能是数据位或停止位设置不正确。当前设置如下:波特率:9600 数据位:8 校验位:无 停止位:1在 Arduino 代码中使用 Serial.begin(9600) 进行初始化。 Serial.begin(9600):- 波特率:9600- 数据位…

合理利用符号,用负反馈解决正反馈系统

首先,系统框图:此处的Kyrg当成是1,aircraft的状态方程系数为:A=[-0.0558 -0.9968 0.0802 0.0415; 0.598 -0.115 -0.0318 0; -3.05 0.388 -0.4650 0; 0 0.0805 1 0]; B=[0.00729 -0.475 0.153 0]; C=[0 1 0 0]; D=0;使用函数ss2tf和tf求出系统的传递函数为:sysGs =-0.475 …

若依框架前端表格自适应

1. 背景 问题描述: 如图,若依前端表格高度都是固定写死的,因此会出现底部空一部分,现在希望自适应表格,使得表格一屏展示,且在隐藏查询条件等操作,导致屏幕大小变化时,表格可以同步自适应。问题现状:很多时候,前端开发都是尽可能本机调整到刚刚好的高度,但不同用户不…

CentOS 7 升级 OpenSSH 9.8p1

背景 OpenSSH 官方发布安全通告,披露CVE-2024-6387 OpenSSH Server远程代码执行漏洞。 环境操作系统 内核 openssh 版本 openssl 版本7.8.2003 3.10.0-1127 7.4p1 1.0.2k-fips安装编译软件和下载 OpenSSH9.8p1 软件包 mkdir -p /data/software cd /data/software/yum install…

ComfyUI基础篇:为什么要学 ComfyUI?

前言:在AI生成图像领域,有许多产品,例如 Midjourney 和 Stability AI 等。为什么要学习 ComfyUI 呢?我斗胆带大家一起分析一下。目录1.Midjourney VS Stable Diffusion2.SD Web UI VS ComfyUI3.总结Midjourney VS Stable Diffusion在回答这个问题之前,我觉得有必要介绍下目…

功能齐全!一套基于AGPL3开源协议开源的智慧物业社区系统!!

ejyy —— 一套开源的智慧物业解决方案。实现了微信公众号、小程序、PC、H5、智能硬件多端打通,旨在提升物业公司效率、规范物业服务流程、提升物业服务满意度、加强小区智慧化建设、便捷业主服务。大家好,我是 Java陈序员。 今天,给大家介绍一套开源的物业社区管理系统,涵…

关于搭建可商用AI平台的小感想

AI时代已经到来,建立自己的AI平台不仅能提升技能,还能带来更多职业和商业机会。我们的开源AI平台解决了技术难题,并提供全套商业化解决方案,让你专注于业务拓展。想学习从0-1搭建AI平台的朋友,欢迎加入我们的开发者交流群,一起交流学习。前言 AI时代已经到来,从智能客服…

QChartView显示实时更新的温度曲线图(二)

目录参考图说明1. 项目结构2. TempChartView.pro3. main.cpp4. TemperatureSeries.qml5. main.qml详细说明 参考图说明Qt Charts 提供了一系列使用图表功能的简单方法。它使用Qt Graphics View Framework 图形视图框架,因此可以很容易集成到用户界面。可以使用Qt Charts作为QW…

程序人生日记20240704|工作零食:米饭+十分米莲藕汁+饼干(减脂记录)

程序员的工作饮食减脂记录打卡 餐别:早餐 零食详情:(同事给的不算统计内) 零食名称:十分米莲藕汁配饼干 其他选择:米饭+海盐饼干。 大致热量估算: 莲藕汁约50卡,低脂全麦饼干2片约80卡,米饭约500卡,总计约630卡。 初始数据: 体重:90公斤 目标:80公斤 完成情况:完…

开发一个题库系统App和小程序的心得

开发一个题库系统App和小程序的心得序言 对于一名开发者来说,独自开发一款小程序与App,也许总会有一些疑问:1. 需要掌握哪些技术? 答:java、vue、及常规Linux命令2. 需要多少成本? 答:服务器购买,云服务器新人50多三年; 域名购买,10块的域名够用,后续每年30左右的续…

SFE人才需要具备哪些能力

SFE(销售队伍效力)人才在企业中扮演着至关重要的角色,他们需要具备一系列的能力来确保销售队伍的高效运作和业绩提升。关于SFE的角色和能力,可以从业务理解、数据洞察、向上管理以及效率提升等几个方面来通俗地解释。01 懂业务 SFE人才首先需要深入了解公司的业务,像医药企…

doris 数据库与mysql的不同之处

1.doris与mysqldoris可以使用mysql驱动进行连接,也支持mysql的部分语法。 2.具体分析清空表数据 在mysql中,清空表数据有两种方式: 一种是delete from table_name,一种是truncate table table_name。 而在doris中,清空表数据只能使用truncate table table_name。delete fr…

Kylin V10SP2安装openGauss5.0.2企业版

一、本地系统环境 [root@localhost ~]# cat /etc/os-release NAME="Kylin Linux Advanced Server" VERSION="V10 (Sword)" ID="kylin" VERSION_ID="V10" PRETTY_NAME="Kylin Linux Advanced Server V10 (Sword)" ANSI_COLO…

VMware ESXi 8.0U3 macOS Unlocker OEM BIOS Huawei (华为) FusionServer 定制版

VMware ESXi 8.0U3 macOS Unlocker & OEM BIOS Huawei (华为) FusionServer 定制版VMware ESXi 8.0U3 macOS Unlocker & OEM BIOS Huawei (华为) FusionServer 定制版 ESXi 8.0U3 标准版,Dell (戴尔)、HPE (慧与)、Lenovo (联想)、Inspur (浪潮)、Cisco (思科)、Hitac…

常见数据摆渡系统全面比较,哪一款才是众望所归?

数据摆渡是一种利用物理隔离或特定设备,在不相连的计算机或系统之间传输数据的方法。其原理主要基于中间层的数据处理和转换,确保数据在不同系统之间能够进行有效的交换和共享。对于企业而言,数据摆渡场景主要发生在企业隔离网间。基于网络安全管理需要,企业采用防火墙等网…

PHP 真的不行了?透过 PHP 的前世今生看真相

时代造就了马云,同样也成就了 PHP。大家好,我是码农先森。 1994年我出生在湖南的农村,就在同年加拿大的拉斯姆斯勒多夫创造了 PHP,这时的 PHP 还只是用 Perl 编写的 CGI 脚本。或许是时间的巧合 PHP 变成了我后半生谋生的手段,当时拉斯姆斯勒多夫写这些脚本的目的,只是为…

智慧校园视频监控系统

智慧校园视频监控系统助力学校传统安防监控智能升级,借助智慧校园视频监控系统可以避免传统视频监控“被动”监控,有效监控价值低,不能及时预警预防的能力。智慧校园视频监控具备大规模智能检测、多场景智能分析、机器自主学习、实时告警、实时分析、全天运行,实现校园管理…

施工现场视频监控系统

施工现场视频监控系统可以从作业人员进入施工现场的入口处就开始对进入人员进行现场视频监控系统的检测识别,如果系统侦查到进入的人员着装穿戴不符合工地企业的进入要求就会立即预警提醒进入人员按照要求整改后再进入施工现场,保证进入施工现场作业人员的着装合规符合要求,…

智慧工地视频监控系统解决方案

智慧工地视频监控系统解决方案赋能传统监控“大脑”思考能力,工地现有视频监控借助智慧工地视频监控系统可以实现对工地现场施工作业的及时识别预警,保障现场作业人员的人身安全及施工企业的现场财产安全,提升施工单位的工地智能化管理水平及安全施工效率。随着科技的发展,…