当前位置: 澳门新濠3559 > 操作系统 > 正文

避免造成重复调用接口出错,进程就是运行中的

时间:2019-11-28 21:09来源:操作系统
一、需求: 1.什么是守护进程 ◆1、程序和进程 概念: Linux上对一个进程名称可能会对应的多个进程号的进程进行监控,如果有多个则输出到一个日志文件。 守护进程是脱离于终端并且

一、需求:

1.什么是守护进程

◆1、程序和进程

概念:

Linux上对一个进程名称可能会对应的多个进程号的进程进行监控,如果有多个则输出到一个日志文件。

守护进程是脱离于终端并且在后台运行的进程。守护进程脱离于终端是为了避免进程在执行过程中的信息在任何终端上显示并且进程也不会被任何终端所产生的终端信息所打断。

程序是为了完成某种任务而设计的软件,比如OpenOffice是程序。什么是进程呢?进程就是运行中的程序。

程序(program)只是一组指令的有序集合。

任务(task)是最抽象的,是一个一般性的术语,指由软件完成的一个活动。一个任务既可以是一个进程,也可以是一个线程。简而言之,它指的是一系列共同达到某一目的的操作。例如,读取数据并将数据放入内存中。这个任务可以作为一个进程来实现,也可以作为一个线程(或作为一个中断任务)来实现。

以上问题针对的是一个定时程序还未运行结束,到下一个时刻程序又运行起来了,避免造成重复调用接口出错。

例如 apache, nginx, mysql 都是守护进程

一个运行着的程序,可能有多个进程。 比如 LinuxSir.Org 所用的WWW服务器是apache服务器,当管理员启动服务后,可能会有好多人来访问,也就是说许多用户来同时请求httpd服务,apache服务器将会创建有多个httpd进程来对其进行服务。

避免造成重复调用接口出错,进程就是运行中的程序。进程(process)常常被定义为程序的执行。可以把一个进程看成是一个独立的程序,在内存中有其完备的数据空间和代码空间。一个进程所拥有的数据和变量只属于它自己。

二、解决:

2.为什么开发守护进程

1.1 进程分类;

进程是表示资源分配的基本单位,又是调度运行的基本单位。例如,用户运行自己的程序,系统就创建一个进程,并为它分配资源,包括各种表格、内存空间、磁盘空间、I/O设备等。然后,把该进程放人进程的就绪队列。进程调度程序选中它,为它分配CPU以及其它有关资源,该进程才真正运行。所以,进程是系统中的并发执行的单位。
#!/bin/sh
#(nohup pid_monitor.sh &)   #被监控的进程放在后台运行,需要用nohup不挂断的执行
#export LANG=en_US.utf-8
while true       #死循环不断监控后台运行的进程
do
    pid_num=`ps -ef | grep -v grep|grep ROOT_SUB_i2_data| awk '{print $2}'|wc -l`  #取后台运行程序的进程号数量


    if [ $pid_num  -gt 1 ];         #判断被监控的进程数是否大于1,注意分号,shell和python是有区别的
    then
        echo '监控到多个异常进程:' >>pid_monitor.log
        ps -ef |grep -v grep|grep ROOT_SUB_i2_data| awk '{print $2,$5}' >>pid_monitor.log #打印进程号和启动时间
    else
        echo `date` '只监控到的进程个数为:' $pid_num '个' >>pid_monitor.log
        sleep 30 #休息30秒 
    fi
done

很多程序以服务形式存在,他没有终端或UI交互,它可能采用其他方式与其他程序交互,如TCP/UDP Socket, UNIX Socket, fifo。程序一旦启动便进入后台,直到满足条件他便开始处理任务。

进程一般分为交互进程、批处理进程和守护进程三类。

在Mac、Windows NT等采用微内核结构的操作系统中,进程的功能发生了变化:它只是资源分配的单位,而不再是调度运行的单位。在微内核系统中,真正调度运行的基本单位是线程。因此,实现并发功能的单位是线程。

 

3.何时采用守护进程开发应用程序

值得一提的是守护进程总是活跃的,一般是后台运行,守护进程一般是由系统在开机时通过脚本自动激活启动或超级管理用户root来启动。比如在Fedora或Redhat中,我们可以定义httpd 服务器的启动脚本的运行级别,此文件位于/etc/init.d目录下,文件名是httpd,/etc/init.d/httpd 就是httpd服务器的守护程序,当把它的运行级别设置为3和5时,当系统启动时,它会跟着启动。

线程(tread)则是某一进程中一路单独运行的程序。也就是说,线程存在于进程之中。一个进程由一个或多个线程构成,各线程共享相同的代码和全局数据,但各有其自己的堆栈。由于堆栈是每个线程一个,所以局部变量对每一线程来说是私有的。由于所有线程共享同样的代码和全局数据,它们比进程更紧密,比单独的进程间更趋向于相互作用,线程间的相互作用更容易些,因为它们本身就有某些供通信用的共享内存:进程的全局数据。

 

以我当前的需求为例,我需要运行一个程序,然后监听某端口,持续接受服务端发起的数据,然后对数据分析处理,再将结果写入到数据库中; 我采用ZeroMQ实现数据收发。

[[email protected] ~]# chkconfig --level 35 httpd on

一个进程和一个线程最显著的区别是:线程有自己的全局数据。线程存在于进程中,因此一个进程的全局变量由所有的线程共享。由于线程共享同样的系统区域,操作系统分配给一个进程的资源对该进程的所有线程都是可用的,正如全局数据可供所有线程使用一样

三、参考

如果我不采用守护进程方式开发该程序,程序一旦运行就会占用当前终端窗框,还有受到当前终端键盘输入影响,有可能程序误退出。

由于守护进程是一直运行着的,所以它所处的状态是等待请求处理任务。比如,我们是不是访问 LinuxSir.Org ,LinuxSir.Org 的httpd服务器都在运行,等待着用户来访问,也就是等待着任务处理。

线程是进程中执行运算的最小单位,亦即执行处理机调度的基本单位。如果把进程理解为在逻辑上操作系统所完成的任务,那么线程表示完成该任务的许多可能的子任务之一。例如,假设用户启动了一个窗口中的数据库应用程序,操作系统就将对数据库的调用表示为一个进程。假设用户要从数据库中产生一份工资单报表,并传到一个文件中,这是一个子任务;在产生工资单报表的过程中,用户又可以输人数据库查询请求,这又是一个子任务。这样,操作系统则把每一个请求――工资单报表和新输人的数据查询表示为数据库进程中的独立的线程。线程可以在处理器上独立调度执行,这样,在多处理器环境下就允许几个线程各自在单独处理器上进行。操作系统提供线程就是为了方便而有效地实现这种并发性

4.守护进程的安全问题

1.2 进程的属性;

引入线程的好处

我们希望程序在非超级用户运行,这样一旦由于程序出现漏洞被骇客控制,攻击者只能继承运行权限,而无法获得超级用户权限。

进程IDPID):是唯一的数值,用来区分进程;

(1)易于调度。
(2)提高并发性。通过线程可方便有效地实现并发性。进程可创建多个线程来执行同一程序的不同部分。
(3)开销少。创建线程比创建进程要快,所需开销很少。。
(4)利于充分发挥多处理器的功能。通过创建多线程进程(即一个进程可具有两个或更多个线程),每个线程在一个处理器上运行,从而实现应用程序的并发性,使每个处理器都得到充分运行。

我们希望程序只能运行一个实例,不运行同事开启两个以上的程序,因为会出现端口冲突等等问题。

父进程和父进程的IDPPID);

联系:

5.怎样开发守护进程

启动进程的用户IDUID)和所归属的组GID);

进程与线程区别与联系

例 1. 守护进程例示

进程状态:状态分为运行R、休眠S、僵尸Z;

(1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。
(2)资源分配给进程,同一进程的所有线程共享该进程的所有资源。
(3)处理机分给线程,即真正在处理机上运行的是线程。
(4)线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。

logger = $logger; #} #protected $logger; protected static $dbh; public function __construct() { } public function run(){ $dbhost = '192.168.2.1'; // 数据库服务器 $dbport = 3306; $dbuser = 'www'; // 数据库用户名 $dbpass = 'qwer123'; // 数据库密码 $dbname = 'example'; // 数据库名 self::$dbh = new PDO("mysql:host=$dbhost;port=$dbport;dbname=$dbname", $dbuser, $dbpass, array( /* PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES 'UTF8'', */ PDO::MYSQL_ATTR_COMPRESS => true, PDO::ATTR_PERSISTENT => true ) ); } protected function getInstance(){ return self::$dbh; }}/* the collectable class implements machinery for Pool::collect */class Fee extends Stackable { public function __construct { $trades = explode; $this->data = $trades; print_r; } public function run() { #$this->worker->logger->log("%s executing in Thread #%lu", __CLASS__, $this->worker->getThreadId; try { $dbh = $this->worker->getInstance(); $insert = "INSERT INTO fee(ticket, login, volume, `status`) VALUES(:ticket, :login, :volume,'N')"; $sth = $dbh->prepare; $sth->bindValue(':ticket', $this->data[0]); $sth->bindValue(':login', $this->data[1]); $sth->bindValue(':volume', $this->data[2]); $sth->execute(); $sth = null; /* ...... */ $update = "UPDATE fee SET `status` = 'Y' WHERE ticket = :ticket and `status` = 'N'"; $sth = $dbh->prepare; $sth->bindValue(':ticket', $this->data[0]); $sth->execute(); //echo $sth->queryString; //$dbh = null; } catch { $error = sprintf("%s,%sn", $mobile, $id ); file_put_contents("mobile_error.log", $error, FILE_APPEND); } }}class Example { /* config */ const LISTEN = "tcp://192.168.2.15:5555"; const MAXCONN = 100; const pidfile = __CLASS__; const uid = 80; const gid = 80; protected $pool = NULL; protected $zmq = NULL; public function __construct() { $this->pidfile = '/var/run/'.self::pidfile.'.pid'; } private function daemon(){ if (file_exists { echo "The file $this->pidfile exists.n"; exit(); } $pid = pcntl_fork { die; } else if  { // we are the parent //pcntl_wait; //Protect against Zombie children exit; } else { // we are the child file_put_contents($this->pidfile, getmypid; posix_setuid; posix_setgid; return; } } private function start(){ $pid = $this->daemon(); $this->pool = new Pool(self::MAXCONN, ExampleWorker::class, []); $this->zmq = new ZMQSocket, ZMQ::SOCKET_REP); $this->zmq->bind; /* Loop receiving and echoing back */ while ($message = $this->zmq->recv { //print_r; //if{ $this->pool->submit; $this->zmq->send; //}else{ // $this->zmq->send; //} } $pool->shutdown(); } private function stop(){ if (file_exists { $pid = file_get_contents; posix_kill; unlink; } } private function help{ printf("%s start | stop | help n", $proc); } public function main{ if{ printf("please input help parametern"); exit(); } if{ $this->stop(); }else if{ $this->start(); }else{ $this->help; } }}$cgse = new Example;

进程执行的优先级;

(5)划分尺度:线程更小,所以多线程程序并发性更高;

下面是程序启动后进入后台的代码

进程所连接的终端名;

(6)资源分配:进程是资源分配的基本单位,同一进程内多个线程共享其资源;

通过进程ID文件来判断,当前进程状态,如果进程ID文件存在表示程序在运行中,通过代码file_exists实现,但而后进程被kill需要手工删除该文件才能运行

进程资源占用:比如占用资源大小内存、CPU占用量);

(7)地址空间:进程拥有独立的地址空间,同一进程内多个线程共享其资源;

private function daemon(){ if (file_exists { echo "The file $this->pidfile exists.n"; exit(); } $pid = pcntl_fork { die; } else if  { // we are the parent //pcntl_wait; //Protect against Zombie children exit; } else { // we are the child file_put_contents($this->pidfile, getmypid; posix_setuid; posix_setgid; return; } }

1.3 父进程和子进程;

(8)处理器调度:线程是处理器调度的基本单位;

程序启动后,父进程会推出,子进程会在后台运行,子进程权限从root切换到指定用户,同时将pid写入进程ID文件。

他们的关系是管理和被管理的关系,当父进程终止时,子进程也随之而终止。但子进程终止,父进程并不一定终止。比如httpd服务器运行时,我们可以杀掉其子进程,父进程并不会因为子进程的终止而终止。

(9)执行:每个线程都有一个程序运行的入口,顺序执行序列和程序的出口,但线程不能单独执行,必须组成进程,一个进程至少有一个主线程。简而言之,一个程序至少有一个进程,一个进程至少有一个线程。

程序停止,只需读取pid文件,然后调用posix_kill; 最后将该文件删除。

在进程管理中,当我们发现占用资源过多,或无法控制的进程时,应该杀死它,以保护系统的稳定安全运行;

进程和程序区别和联系

private function stop(){ if (file_exists { $pid = file_get_contents; posix_kill; unlink; } }

程序是为了完成某种任务而设计的软件,比如OpenOffice是程序。什么是进程呢?进程就是运行中的程序。 一个运行着的程序...

(1)程序只是一组指令的有序集合,它本身没有任何运行的含义,它只是一个静态的实体。而进程则不同,它是程序在某个数据集上的执行。进程是一个动态的实体,它有自己的生命周期。反映了一个程序在一定的数据集上运行的全部动态过程。

(2)进程和程序并不是一一对应的,一个程序执行在不同的数据集上就成为不同的进程,可以用进程控制块来唯一地标识每个进程。而这一点正是程序无法做到的,由于程序没有和数据产生直接的联系,既使是执行不同的数据的程序,他们的指令的集合依然是一样的,所以无法唯一地标识出这些运行于不同数据集上的程序。一般来说,一个进程肯定有一个与之对应的程序,而且只有一个。而一个程序有可能没有与之对应的进程(因为它没有执行),也有可能有多个进程与之对应(运行在几个不同的数据集上)。

(3)进程还具有并发性和交往性,这也与程序的封闭性不同。

进程和程序区别和联系表现在以下方面:

1)程序只是一组指令的有序集合,它本身没有任何运行的含义,它只是一个静态的实体。而进程则不同,它是程序在某个数据集上的执行。

进程是一个动态的实体,它有自己的生命周期。它因创建而产生,因调度而运行,因等待资源或事件而被处于等待状态,因完成任务而被撤消。反映了一个程序在一定的数据集上运行的全部动态过程。

2)进程和程序并不是一一对应的,一个程序执行在不同的数据集上就成为不同的进程,可以用进程控制块来唯一地标识每个进程。而这一点正是程序无法做到的,由于程序没有和数据产生直接的联系,既使是执行不同的数据的程序,他们的指令的集合依然是一样的,所以无法唯一地标识出这些运行于不同数据集上的程序。一般来说,一个进程肯定有一个与之对应的程序,而且只有一个。而一个程序有可能没有与之对应的进程(因为它没有执行),也有可能有多个进程与之对应(运行在几个不同的数据集上)。

3)进程还具有并发性和交往性,这也与程序的封闭性不同。进程和线程都是由操作系统所体会的程序运行的基本单元,系统利用该基本单元实现系统对应用的并发性。进程和线程的区别在于:

简而言之,一个程序至少有一个进程,一个进程至少有一个线程.

线程的划分尺度小于进程,使得多线程程序的并发性高。

另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。

线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。

从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。

进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位.

线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源.

一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行。

http://blog.csdn.net/xywlpo/article/details/6749685
澳门新濠3559,http://www.ruanyifeng.com/blog/2013/04/processes_and_threads.html

编辑:操作系统 本文来源:避免造成重复调用接口出错,进程就是运行中的

关键词: