笨小迪 2017-10-10 08:44 采纳率: 0%
浏览 462

php pclose会把其它进程关掉吗?

由于windows系统的原因,重复定时任务的时间间隔不能设置为30秒。
所以想着用php写一个定时任务

 while(true){
        $config = parse_ini_file('config.ini',true);
        foreach($config as $cronName=>$info){
            if(array_key_exists('log_dir',$info) && !empty($info['log_dir'])){
                $outputCommon = ' 1>>'.$info['log_dir'].' 2>&1 &';
            }else{
                $outputCommon = '';
            }
            $runStatus = timeMark($info['run_time']);
            if($runStatus){
                $memory = convert(memory_get_usage(true));
                echo '['.date('Y-m-d H:i:s').'] Task:['.$cronName."]->Is Runing Mem:".$memory."\r\n";
                $handle = popen('cd '.$info['cd_dir'].'&'.$info['common'].$outputCommon,'r');
                pclose($handle);
            }else{
                echo '['.date('Y-m-d H:i:s').']'."Waiting for a task\r\n";
            }
        }
    sleep(1);
}

但是执行的时候,同一个时间执行两个操作会有问题

第一个操作完成后,会pclose,这样好像会把另外一个也结束掉

这个问题要怎么解决呢?求大神们帮帮忙!

  • 写回答

1条回答 默认 最新

  • 你知我知皆知 2024-08-07 00:13
    关注

    以下回答参考 皆我百晓生券券喵儿 等免费微信小程序相关内容作答,并由本人整理回复。

    在PHP中,pclose()函数用于关闭一个打开的文件或连接。然而,在Windows系统上,如果使用popen()来创建一个新的子进程并运行命令(例如,将控制权从父进程转给子进程),那么当子进程退出时,它会自动调用pclose()来关闭其自身的文件描述符,这可能导致其他尚未被处理的任务也被关闭。

    如果你想要在多个子进程中同时执行任务,可以考虑使用守护进程(daemon processes)和信号处理机制。以下是一个简单的示例:

    $pid = pcntl_fork();
    if ($pid == -1) {
        die("Failed to fork");
    } elseif ($pid == 0) { // child process
        exec("/path/to/your/command", $output, $exitcode);
        exit;
    } else { // parent process
        while (true) {
            $config = parse_ini_file('config.ini', true);
            foreach ($config as $cronName => $info) {
                if (!isset($info['log_dir']) || empty($info['log_dir'])) continue;
    
                $outputCommon = '';
                if (array_key_exists('log_dir', $info)) {
                    $outputCommon .= ' 1>>' . $info['log_dir'] . ' 2>&1 &';
                }
    
                $runStatus = timeMark($info['run_time']);
                if ($runStatus) {
                    $memory = convert(memory_get_usage(true));
                    echo '[' . date('Y-m-d H:i:s') . '] Task: [' . $cronName . "]->Is Running Mem:" . $memory . "\r\n";
    
                    $handle = popen('/path/to/your/command &/' . $info['common'] . $outputCommon, 'r');
                    pclose($handle);
    
                    break; // Exit the loop after one run status is completed
                } else {
                    echo '[' . date('Y-m-d H:i:s') . '] Waiting for a task\r\n';
                }
            }
    
            sleep(1); // Sleep for 1 second before checking again
        }
    }
    

    这个示例中的exec()函数负责运行子进程,并且通过pcntl_fork()创建了一个新的子进程。每个子进程都会在其自己的环境变量中运行指定的命令。在循环中检查每个任务的状态,并在状态改变后继续执行下一个任务。这种方法允许你在同一时刻执行多个任务,并确保它们不会互相干扰。

    评论

报告相同问题?