热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

让类/进程/脚本「单身」的方法

每日一句英语学习,每天进步一点点:Betternottoignorethepastbutlearnfromitinstead.Otherwise,hi


每日一句英语学习,每天进步一点点:
  • "Better not to ignore the past but learn from it instead. Otherwise, history has a way of repeating itself."

  • 「最好不要无视过去,而是从中汲取经验教训,否则,历史会有重演的时候。」


前言

有某些场景下,我们不希望有多个相同的 Linux 进程 或 Shell 脚本同时执行,因为相同进程同时执行,可能会破坏数据的一致性

当然还有在 C++ 代码里,有时希望保证程序中一个类只有一个实例,并提供一个访问它的全局访问点,也就是所谓的「单例模式」。只有一个实例很重要,比如一个打印机可以有多个打印任务,但是只有一个正在工作的任务,一个系统只能有一个窗口管理器或文件系统。 

接下来,简单介绍下:

  • Linux 命令的方式控制进程是「单例」的方式;

  • C 代码单进程控制的实现;

  • C++ 线程安全的「单例模式」实现。

正文

flock 命令为脚本加锁

可以用flock命令为 Shell 脚本加锁。当多个进程可能会执行同一个脚本,这些进程需要保证其它进程没有在操作,以免重复执行。通常,这样的进程会使用一个「锁文件」,也就是建立一个文件来告诉别的进程自己在运行,如果检测到那个文件存在则认为有操作同样数据的进程在工作

flock命令来为脚本加锁,如下命令:

flock -xn <锁文件> -c 

  • -x : 获取一个排它锁,或者称为写入锁,为默认项

  • -n : 非阻塞模式,当获取锁失败时,返回 1 而不是等待

  • -c : 执行命令或脚本

实战演示

1. 编写一个测试脚本 test.sh

#! /bin/bash
echo "Hello World"
sleep 1000

2. flock 命令给脚本加锁

flock -xn ./test.lock -c "/root/test.sh"

3. 开启另外一个 bash 窗口运行同个的脚本

另外一个 bash 窗口运行了同个脚本后,未获取到锁直接返回了,直到上一个脚本运行完毕,这个才可以开始正常运行。

应用的场景

可以在 Linux 定时器/etc/crontab里运用flock命令为脚本加锁,防止重复执行:

* * * * * (flock -xn ./test.lock -c "/root/test.sh")


C 代码实现单进程控制

通常后台服务器程序都必须有且只有一个进程,那么如何控制单进程呢?思想和上面提到的flock命令差不多。

我们可以通过flock系统接口函数对某个文件进行加锁

  • 若加锁不正常,说明后台服务进程已经在运行了,这时则直接报错退出;

  • 若加锁成功,说明后台服务进程没有在运行,这时可以正常启用进程。

用 flock 函数实现的单进程控制代码

C 程序单进程控制

实战演练

我们在 main 函数使用上面的函数:

int main(void)
{//进程单实例运行检测if(0 != server_is_running()){printf("myserver process is running!!!!! Current process will exit !\n");return -1;}while(1){printf("myserver doing ... \n");sleep(2);}return 0;
}

运行程序,可知进程pid是 6965

[root@lincoding singleprocess]# ./myserver 
server is not running! begin to run..... pid=6965
myserver doing ... 
myserver doing ... 

此时,再运行同个程序,这时会报错退出,因为检测到程序已经在运行中,不可以起另外一个进程。

[root@lincoding singleprocess]# ./myserver 
server is runing now! errno=11
myserver process is running!!!!! Current process will exit !


C++ 单例模式

单例模式指在整个系统生命周期里,保证一个类只能产生一个实例,确保该类的唯一性

单例类的特点:

  • 声明「构造函数和析构函数」为 private 类型,目的禁止外部构造和析构

  • 声明「复制构造和赋值操作」函数为 private 类型,目的是禁止外部拷贝和赋值,确保实例的唯一性

  • 类里有个获取实例的「静态函数」,可以全局访问

还有需要注意的是写单例类时,要注意多线程的竞争的问题,因为可能存在当两个线程同时获取单例对象时,产生出了两个对象,这就违背了单例模式的唯一性。

单例模式实现的方式有很多种,这里推荐一下相对比较简洁的懒汉式单例的两种写法:

在 C++ 11 标准中提出「局部静态变量」初始化具有线程安全性,那么此时写出一个线程安全的单例类,只需要几行代码。

局部静态对象单例模式实现

Single 使用的静态变量是一个「局部静态变量」,因此只有在 Single 的GetInstance()函数被调用时其才会被创建,从而拥有了延迟初始化(Lazy)的效果,提高了程序的启动性能。同时该实例将生存至程序执行完毕。而就 Single 的用户代码而言,其生存期贯穿于整个程序生命周期,从程序启动开始直到程序执行完。

同时,C++ 11 也提供一个新的东西叫std::call_once,配合std::once_flag,可以保证函数在任何情况下只调用一次。

std::call_once 单例模式实现

小结

小结

推荐阅读:
  • 「C++ 篇」答应我,别再if/else走天下了可以吗


关注公众号,后台回复「我要学习」,即可免费获取精心整理「服务器 Linux C/C++ 」成长路程(书籍资料 + 思维导图



推荐阅读
  • 1.判断磁盘使用空间df-h|grep-vFile|seds%g|awk{if($580)print使用空间超过了80%:,$6}或#!binbash#Filename:di ... [详细]
  • linux 循环 cpu使用率脚本,Linux Shell脚本监视CPU利用率,达到设置的CPU利用率时发送电子邮件...
    有很多开源监控工具可用于监控Linux系统性能,当系统达到给定的阈值限制时,它将发送电子邮件警报。它监视CPU利用率、内存利用率、交换利用率、磁盘空间利 ... [详细]
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • 本文介绍了使用PHP实现断点续传乱序合并文件的方法和源码。由于网络原因,文件需要分割成多个部分发送,因此无法按顺序接收。文章中提供了merge2.php的源码,通过使用shuffle函数打乱文件读取顺序,实现了乱序合并文件的功能。同时,还介绍了filesize、glob、unlink、fopen等相关函数的使用。阅读本文可以了解如何使用PHP实现断点续传乱序合并文件的具体步骤。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • 本文总结了Linux下多线程执行shell脚本的4种方法,包括切换到工作目录执行、使用绝对路径执行、直接使用bash或sh执行。同时介绍了为什么需要加上"./"来执行脚本的原因。 ... [详细]
  • 深入解析Linux下的I/O多路转接epoll技术
    本文深入解析了Linux下的I/O多路转接epoll技术,介绍了select和poll函数的问题,以及epoll函数的设计和优点。同时讲解了epoll函数的使用方法,包括epoll_create和epoll_ctl两个系统调用。 ... [详细]
  • Linux下安装免费杀毒软件ClamAV及使用方法
    本文介绍了在Linux系统下安装免费杀毒软件ClamAV的方法,并提供了使用该软件更新病毒库和进行病毒扫描的指令参数。同时还提供了官方安装文档和下载地址。 ... [详细]
  • 微软评估和规划(MAP)的工具包介绍及应用实验手册
    本文介绍了微软评估和规划(MAP)的工具包,该工具包是一个无代理工具,旨在简化和精简通过网络范围内的自动发现和评估IT基础设施在多个方案规划进程。工具包支持库存和使用用于SQL Server和Windows Server迁移评估,以及评估服务器的信息最广泛使用微软的技术。此外,工具包还提供了服务器虚拟化方案,以帮助识别未被充分利用的资源和硬件需要成功巩固服务器使用微软的Hyper - V技术规格。 ... [详细]
  • 1Lock与ReadWriteLock1.1LockpublicinterfaceLock{voidlock();voidlockInterruptibl ... [详细]
  • mysql自动打开文件_让docker中的mysql启动时自动执行sql文件
    本文提要本文目的不仅仅是创建一个MySQL的镜像,而是在其基础上再实现启动过程中自动导入数据及数据库用户的权限设置,并且在新创建出来的容器里自动启动My ... [详细]
  • 【BP靶场portswigger服务端10】XML外部实体注入(XXE注入)9个实验(全)
    前言:介绍:博主:网络安全领域狂热爱好者(承诺在CSDN永久无偿分享文章)。殊荣:CSDN网络安 ... [详细]
  • Jenkins教程:使用Jenkins进行持续集成
    【注】本文译自:https:www.edureka.coblogjenkins-tutorial本文将重点介绍Jenkins架构和Jenkins构建管道,并向您展示如何在Jenki ... [详细]
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
author-avatar
春天故事围脖_381_478
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有