C中线程信号控制

news2024/11/24 16:44:45

一、场景介绍

存在三个线程,一个主线程和两个子线程(子线程数量不固定)。为了节省频繁创建销毁线程造成的资源浪费,将这些线程设置为常驻线程。但这样引入了一个新的问题,如何协调这些线程完成工作。

主线程内是循环检测某个文件夹内文件的变动,当文件夹内出现新的文件时,更新可拷贝文件列表,并告知子线程开始干活;子线程拷贝结束后需要告知主线程任务完成了,主线程开始下一轮检测。

二、解决方法

1、临时线程

主线程每次检测完毕后,新建子线程执行拷贝任务,并阻塞等待线程任务的结束。

#include "main.h"

void *filecopy_thread(void *args)
{
    pthread_t id = pthread_self();
    PTHREAD_ARGS *thread_args = (PTHREAD_ARGS *)args;
    string dst_dir = thread_args->dst_dir;
    while (1)
    {
        // get the file to copy
        pthread_mutex_lock(thread_args->mutex);
        // exit when the list is empty
        if (thread_args->file_list.empty())
        {
            pthread_mutex_unlock(thread_args->mutex);
            break;
        }
        string src_file = thread_args->file_list.back();
        thread_args->file_list.pop_back();
        pthread_mutex_unlock(thread_args->mutex);
        copy_file(src_file, dst_dir);
    }
    return NULL;
}


int main(int argc, char **argv)
{
    while(1)
    {
        bool is_switch = oracle.is_redolog_switch();

        // judge whether the redolog has bean switched
        if ( is_switch )
        {
            printf("pthread create\n");
            pthread_t *pthread_list = (pthread_t *)malloc(sizeof(pthread_t) * cfg_utils.m_filecopy_pcount);
            if (!pthread_list)
            {
                LOG_F(ERROR, "pthread list created failed");
                continue;
            }
            pthread_mutex_t mutex;
            pthread_mutex_init(&mutex, NULL);
            PTHREAD_ARGS pthread_args = {file_list_src, &mutex, cfg_utils.m_logbk_syspath, &oncebk_count};
            
            struct timeval start, end;
            gettimeofday(&start, NULL);
                        
            // start file copy thread
            for (int i = 0; i < cfg_utils.m_filecopy_pcount; i++)
            {
                 printf("creating pthread(%d)\n", i + 1);
                pthread_create(pthread_list + i, NULL, filecopy_thread, &pthread_args);
            }
            // block until all file has copied
            for (int i = 0; i < cfg_utils.m_filecopy_pcount; i++)
            {
                pthread_join(pthread_list[i], NULL);
            }
            
            gettimeofday(&end, NULL);
            double timeuse = ( end.tv_sec - start.tv_sec ) + (end.tv_usec - start.tv_usec)/1000000.0;
            printf("%.1lf(s)\n", timeuse);
            
            pthread_mutex_destroy(&mutex);
            free(pthread_list);

        }
        sleep(cfg_utils.m_bk_cycle);
    }
    return 0;
}

(1)优点

逻辑简单

(2)缺点

频繁创建与销毁线程,资源浪费。

2、全局变量信号

定义一个全局变量作为线程的控制信号。

主线程将该信号设置为子线程的个数的负数,以启动子线程。

当该信号小于 0 时,子线程开始启动。子线程的启动与任务完毕都需要将该信号加一。

当主线程检测到该信号为线程总数时推导子线程本次任务结束。

(1)优点

子线程作为常驻线程,节省了一定的资源

(2)缺点

子线程与主线程在等待信号的过程中要么造成 CPU 的空转,要么 sleep 会增加程序的处理时延。

而且,子线程启动与结束都对全局信号进行加一的操作,极端情况(某些线程执行速度存在极端差异)下可能造成信号控制的紊乱。

3、信号量

使用两组信号:start_signal 和 over_signal。

主线程启动子线程时,需要将 start_signal 赋值为子线程数,over_signal 赋值为0.

子线程执行down(start_signal) ,该操作执行成功即可执行任务逻辑,执行完后 up(over_signal)。

主线程需要执行 num 次down(over_signal)操作,只有所有子线程执行结束,该操作才可以执行完成。

在等待执行信号down和up的过程中,线程都是阻塞的,不会造成 CPU 的空转,当信号可操作时也会立即执行,不会增加操作时延。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Webgl实现的天气效果(下雨、下雪)

一、下雨效果如图&#xff1a; 还有一种雨水效果也不错 114 Three.js实现深度遮挡的下雨特效 | 暮志未晚-中文案例网 二、下雪的效果 57 Three.js 使用粒子实现下雪特效 | 暮志未晚-中文案例网 还有一种是通过网页CSS的形式做的2D雪效果 集合在一起的源码&#xff1a; https…

编译原理学习笔记17——语义分析和中间代码生成2

编译原理学习笔记17——语义分析和中间代码生成217.1 赋值语句的翻译17.2数组元素引用的翻译17.3 类型转换17.1 赋值语句的翻译 简单算术表达式及赋值语句 赋值语句生成三地址代码的S-属性文法 赋值语句生成三地址代码的S-属性文法 产生赋值语句三地址代码的翻译模式 产…

你真的了解工厂设计模式吗?(简单工厂模式+工厂方法模式+抽象工厂模式)

工厂解决的问题 客户端在调用是不想判断实例化哪一个类或者实例化的过程过于复杂。在工厂模式中&#xff0c;具体的实现类创建过程对客户端是透明的&#xff0c;客户端不决定具体实例化哪一个类&#xff0c;而是交由“工厂”来实例化。 简单工厂模式 类图 简单工厂模式由三类…

Git GitHub纯新手入门教程

参考视频&#xff1a;Github 新手够用指南 | 全程演示&个人找项目技巧放送_哔哩哔哩_bilibili40 分钟学会 Git | 日常开发全程大放送&个搭配GitHub_哔哩哔哩_bilibiliGit和GitHub分别是什么Git是一个运行在电脑上的版本控制软件&#xff08;保存代码各个阶段历史记录的…

在使用定时器过程中存在的那些陷阱

在使用定时器的过程中&#xff0c;如果你不了解定时器的一些细节&#xff0c;那么很有可能掉进定时器的一些陷阱里&#xff0c;函数 setTimeout 在时效性上面有很多先天的不足&#xff0c;所以对于一些时间精度要求比较高的需求&#xff0c;应该有针对性地采取一些其他的方案 …

【回眸】牛客网刷刷刷(四)软件工程(续)ZooKeeper字符串链表(专题)

前言 本篇博客为笔者刷客观笔试题时做的一些记录以供以后复习时翻阅&#xff0c;如果能够帮到您是最大的荣幸&#xff01;如果能给笔者一个三连将感激不尽&#xff01; 知识点串烧 软件工程专题&#xff08;续上篇&#xff09; 有一些可维护特性是相互促进的&#xff0c;如…

【技术美术图形部分】PBR Disney原则的BRDF 次表面散射模型

写在前面 补充去年遗漏下的知识。很多叙述都是参考了众多大佬的文章&#xff01;因为是作为个人学习总结的博客&#xff0c;所以直接卑微的借鉴过来了&#xff0c;后面会给出所有参考的文章。 另外&#xff0c;放上一个忘了在哪一篇知乎评论里的截图&#xff1a; 说的蛮好。 …

MySQL基础篇笔记

文章目录导入表的问题第3章_最基本的SELECT语句1. SQL语言的规则和规范1) 基本规则2) SQL大小写规范&#xff08;建议遵守&#xff09;3) 注释4) 命名规则2. 基本的SELECT语句1) SELECT ... FROM2) 列的别名3) 去除重复行4) 空值参与运算5) 着重号 6) 查询常数3. 显示表结构4. …

贪心算法(基础)

目录 一、什么是贪心&#xff1f; &#xff08;一&#xff09;以教室调度问题为例 1. 问题 2. 具体做法如下 3. 因此将在这间教室上如下三堂课 4. 结论 &#xff08;二&#xff09;贪心算法介绍 1. 贪心算法一般解题步骤 二、最优装载问题 &#xff08;一&#xf…

智能驾驶 车牌检测和识别(四)《Android实现车牌检测和识别(可实时车牌识别)》

智能驾驶 车牌检测和识别&#xff08;四&#xff09;《Android实现车牌检测和识别&#xff08;可实时车牌识别&#xff09;》 目录 智能驾驶 车牌检测和识别&#xff08;四&#xff09;《Android实现车牌检测和识别&#xff08;可实时车牌识别&#xff09;》 1. 前言 2. 车…

SLAM数学知识回顾

文章目录1、三角函数2、向量运算&#xff08;1&#xff09;负向量&#xff08;2&#xff09;向量的模&#xff08;3&#xff09;标量与向量的运算&#xff08;4&#xff09;标准化向量&#xff08;5&#xff09;向量的加法和减法&#xff08;6&#xff09;距离公式&#xff08;…

三十七、Kubernetes1.25中数据存储第三篇

1、概述在前面已经提到&#xff0c;容器的生命周期可能很短&#xff0c;会被频繁地创建和销毁。那么容器在销毁时&#xff0c;保存在容器中的数据也会被清除。这种结果对用户来说&#xff0c;在某些情况下是不乐意看到的。为了持久化保存容器的数据&#xff0c;kubernetes引入了…

计算机视觉OpenCv学习系列:第十部分、实时人脸检测

第十部分、实时人脸检测第一节、实时人脸检测1.OpenCV人脸检测支持演化2.OpenCV DNN检测函数3.代码练习与测试学习参考第一节、实时人脸检测 1.OpenCV人脸检测支持演化 OpenCV4 DNN模块 DNN- 深度神经网络 来自另外一个开源项目tiny dnnOpenCV3.3正式发布最新版本OpenCV4.5.…

网络编程 之 epoll

epoll 参数设置 events设置 ev.events EPOLLIN | EPOLLET;epoll实现TCP通讯时&#xff0c;events通用设置如上&#xff0c;EPOLLIN代表可socket套接字可接收数据&#xff0c;EPOLLET代表边沿触发。在服务器端, 接受客户端连接的socket不能设置为EPOLLOUT&#xff0c;只设置E…

【5】【TypeScript】(TypeScript=Type+JavaScript)

Typescript 相比js特有 类型系统&#xff1b;对象的接口DOM操作时候需要进行类型断言上面三个实际是类型系统的三处体现枚举js中&#xff0c;-号可以强制转换为数值&#xff0c;ts不行 所有合法的js都是ts 1、安装 安装进度卡住可以用淘宝镜像 &#xff08;在后面加 --registr…

Spring Cloud Hystrix有什么作用?

在微服务架构中&#xff0c;通常会存在多个服务层调用的情况&#xff0c;如果基础服务出现故障可能会发生级联传递&#xff0c;导致整个服务链上的服务不可用&#xff0c;如图1所示。图1 服务故障的级联传递在图1中&#xff0c;A为服务提供者&#xff0c;B为A的服务调用者&…

反欺诈(羊毛盾)API有什么作用?

肯定很多企业、商家都遭受过羊毛党的侵入&#xff0c;比如恶意注册、刷单、领用的行为。羊毛党具体有哪些危害呢&#xff1f; 羊毛党的危害 虚假用户裂变&#xff1a;识别在游戏解锁、红包裂变、助力砍价、电商拼团等用户拉新活动中作弊行为。虚假登录注册&#xff1a;防止机…

Java基于springboot大学生宿舍寝室考勤人脸识别管理系统

简介 Java基于springboot开发的大学生寝室管理系统宿舍管理系统。学生可以查找寝室和室友信息&#xff0c;可以申请换寝室&#xff0c;申请维修&#xff0c;寝室长提交考勤信息&#xff08;宿管确认学生考勤信息&#xff09;&#xff0c;补签&#xff0c;查看寝室通报&#xf…

FPGA纯verilog代码实现图像缩放,两种插值算法任意尺寸缩放,提供3套工程源码

目录1、设计思路和架构2、纯verilog代码搭建&#xff0c;不带任何ip3、双线性插值和邻域插值算法4、vivado和matlab联合仿真及结果5、工程代码1&#xff1a;720P原始摄像头采集显示6、工程代码2&#xff1a;720P缩小到800x600P显示7、工程代码3&#xff1a;720P缩放大1920x1080…

结合FPGA和NVIDIA Jetson Orin NX 系统的视觉边缘计算机

边缘计算机采用NVIDIA Jetson Orin NX模块化系统和高带宽图像采集卡&#xff0c;用于实时图像采集计算和人工智能处理。虹科与一家专注于高速图像采集和处理的以色列科技公司Gidel合作&#xff0c;今天宣布新的NVIDIA Jetson Orin NX™ 16GB模块化系统(SoM)将被添加到Gidel的Fa…