zoukankan      html  css  js  c++  java
  • 浅谈Linux Process status,环境锁

    这两天在处理一个相应问题,一个系统希望实行命令互斥,举个例子就是如果我打开了两个命令窗口,分别在这两个窗口中运行两种操作,这些操作是互斥的,即命令2要等待命令1执行完成后再执行。

    这看似可以用简单的锁机制来实现,但实际处理时还要判断1号窗口的进程状态,用户2不会无线等待用户1的命令执行,会去系统中查看用户1的命令执行情况,如果是正在执行则继续等待,如果这个进程被暂停或者有其他情况,则用户2可以从反馈中知道具体信息

     1 sub lock_environment {
     2     my ($self) = @_;
     3 
     4     return SUCCESS if $self->get_parent();
     5     my $process_info = $self->get_process_info();
     6 
     7     while ($self->_validate_environment_lock() == ERR_ENV_LOCKED) {
     8         printf(
     9             "%s is running cvc, PID: %s, will retry in 10 seconds, please wait...........
    ",
    10             $process_info->{user_id},
    11             $process_info->{process_id}
    12         );
    13         sleep(10);
    14     }
    15 
    16     my @ret = $self->_update_env_lock_info(
    17         $$,
    18         $self->get_login_id(),
    19         $self->get_current_environment(),
    20         strftime("%Y-%m-%d %H:%M:%S", localtime()));
    21     return @ret unless $ret[0] == SUCCESS;
    22 
    23     return SUCCESS;
    24 }
    lock_environment
     1 sub _validate_environment_lock {
     2     my ($self) = @_;
     3 
     4     my $process_info = $self->get_process_info();
     5 
     6     return SUCCESS if (!$process_info);
     7 
     8     my @rets = $self->_get_process_status($process_info->{process_id});
     9 
    10     my $process_detail = $rets[1];
    11     my @post_process_detail;
    12     foreach my $str (@$process_detail) {
    13         $str =~ s/s//g;
    14         push @post_process_detail, $str;
    15     }
    16     my @present_pid = grep {($process_info->{process_id}.$process_info->{user_id}) eq $_ } @$process_detail;
    17 
    18     return ERR_ENV_LOCKED if (
    19         ((scalar(@present_pid)) >0) &&
    20         $process_info->{env} eq $self->get_current_environment()
    21     );
    22 
    23     $self->unlock_environment();
    24 
    25     return SUCCESS;
    26 
    27 }
    Validate_environment_lock
     1 sub _get_process_status {
     2     my ($self, $process_id) = @_;
     3 
     4     my @rets;
     5     return (ERR_PROCESS_ID) unless $process_id ;
     6 
     7     $self->_run_cmd_as(
     8         sprintf(
     9             "ps -p %s -o pid -o user",
    10             $process_id
    11         ),
    12         sub {
    13             my ($line) = @_;
    14             push @rets, $line;
    15 
    16             $self->_log($line);
    17         }
    18     );
    19     return (SUCCESS, @rets);
    20 }
    Get_process_status
     1 sub _run_cmd_as {
     2     my ($self, $cmd, $callback, $dir) = @_;
     3 
     4     my $cmd2 = $cmd;
     5     my $run_as_user = $self->get_run_as_user();
     6     my $work_dir = $dir || $self->get_public_env_dir();
     7 
     8     # The -H switch instructs sudo to set $HOME to target users
     9     # which is expected by git
    10     my @parts = split(/&&/, $cmd);
    11     foreach my $p (@parts) {
    12         next if $p =~ /sudo -u/;
    13         $p = sprintf(
    14             "sudo -u %s -H qcvc_operator %s %s",
    15             $run_as_user,
    16             DEFAULT_WRAPPER_PASSWORD,
    17             $p
    18         );
    19     }
    20     $cmd2 = sprintf("cd '%s' && %s ", $work_dir, join('&&', @parts));
    21     return $self->_run_cmd($cmd2, $callback);
    22 }
    _run_cmd_as

    具体实现上用到了一些ps的知识

    ps aux

    a = show processes for all users
    u = display the process's user/owner
    x = also show processes not attached to a terminal

    ps -p xxx  检索pid

    ps -p xxx -o stat 检索pid, report形式只有pid和stat, -o可以多参数,例如ps -p xxx -o stat -o user

    ps aux |grep xxx | grep xxx 针对某些关键词检索pid

    pid是可重用分配的,如果一个pid被kill,在下一某个时刻会它可能会被分配给其他的进程

    STAT狀態位常見的狀態字符

    D 无法中断的休眠状态(通常 IO 的进程);
    R 正在运行可中在队列中可过行的;
    S 处于休眠状态;
    T 停止或被追踪;
    W 进入内存交换  (从内核2.6开始无效);
    X 死掉的进程   (基本很少見);
    Z 僵尸进程;
    < 优先级高的进程
    N 优先级较低的进程
    L 有些页被锁进内存;
    s 进程的领导者(在它之下有子进程);
    l 多进程的(使用 CLONE_THREAD, 类似 NPTL pthreads);
    + 位于后台的进程组;

  • 相关阅读:
    Java精选笔记_EL表达式
    Java精选笔记_文件上传与下载
    Java精选笔记_Servlet事件监听器
    windows 下安装perl Tk 模块
    html 基础
    用grep 筛选fastq 序列
    php 统计fasta 序列长度和GC含量
    perl 截取 fastq文件
    Java_基础知识回顾
    Git_期末总结
  • 原文地址:https://www.cnblogs.com/Raymond-Yang/p/4710042.html
Copyright © 2011-2022 走看看