我有一个PHP脚本,需要花费大量时间才能完成(> 1s)。我想每秒执行一个脚本,无论上一个脚本是否已完成运行。 为此,我使用如下pthread创建了一个C程序:
void *start_instance(void *_args)
{
int id = abs(pthread_self());
arg_for_script* args = _args ;
printf("[SERVICE] start php script on thread %d\n",id);
char cmd[200] ;
sprintf(cmd, "php -f %s %d", args->script_path, id );
system(cmd);
printf("[SERVICE] end of script on thread %d\n", id);
/* Pour enlever le warning */
pthread_exit(NULL);
}
int main(int argc, char* argv[])
{
if(argc < 2)
{
fprintf(stderr, "[SERVICE] Path of php script must be filled\n");
return EXIT_FAILURE;
}
arg_for_script args ;
args.script_path = argv[1];
pthread_attr_t tattr ;
pthread_attr_init(&tattr);
pthread_attr_getinheritsched(&tattr, PTHREAD_EXPLICIT_SCHED);
pthread_attr_getschedpolicy(&tattr, SCHED_RR);
while(1) {
pthread_t thrd;
if(pthread_create(&thrd, &tattr, start_instance, (void *)&args) == -1) {
fprintf(stderr, "[SERVICE] Unable to create thread\n");
return EXIT_FAILURE;
}
sleep(1);
}
pthread_attr_destroy(&tattr);
return EXIT_SUCCESS ;
}
如果我从命令行执行此程序:
./this_program path_of_php_script_as_argv.php
它按例外执行,我有这样的输出:
[SERVICE] start php script on thread 209983744
209983744 | START : Retrieving all new notifications..
209983744 | No new notification
[SERVICE] end of script on thread 209983744
[SERVICE] start php script on thread 218376448
218376448 | START : Retrieving all new notifications..
218376448 | No new notification
[SERVICE] end of script on thread 218376448
[SERVICE] start php script on thread 226769152
226769152 | START : Retrieving all new notifications..
226769152 | No new notification
[SERVICE] end of script on thread 226769152
[SERVICE] start php script on thread 235161856
235161856 | START : Retrieving all new notifications..
235161856 | No new notification
[SERVICE] end of script on thread 235161856
[SERVICE] start php script on thread 243554560
243554560 | START : Retrieving all new notifications..
243554560 | No new notification
[SERVICE] end of script on thread 243554560
现在,我将该程序转换为systemctl服务,以在后台始终执行该程序,但是当我journalctl --follow
(以查看systemctl输出)时,这是我得到的:
Jun 04 15:12:05 vps559055 start[6116]: [SERVICE] start php script on thread 532399872
Jun 04 15:12:05 vps559055 start[6116]: [SERVICE] end of script on thread 532399872
Jun 04 15:12:05 vps559055 start[6116]: [SERVICE] start php script on thread 521811712
Jun 04 15:12:05 vps559055 start[6116]: [SERVICE] end of script on thread 521811712
Jun 04 15:12:05 vps559055 start[6116]: [SERVICE] start php script on thread 513419008
Jun 04 15:12:05 vps559055 start[6116]: [SERVICE] end of script on thread 513419008
Jun 04 15:12:05 vps559055 start[6116]: [SERVICE] start php script on thread 505026304
Jun 04 15:12:05 vps559055 start[6116]: [SERVICE] end of script on thread 505026304
Jun 04 15:12:05 vps559055 start[6116]: [SERVICE] start php script on thread 496633600
// ..... ~100 times, in the same second !
// then, second per second :
Jun 04 15:12:05 vps559055 start[6116]: [SE83728128 | START : Retrieving all new notifications..
Jun 04 15:12:05 vps559055 start[6116]: 83728128 | No new notification
Jun 04 15:12:06 vps559055 start[6116]: 75335424 | START : Retrieving all new notifications..
Jun 04 15:12:06 vps559055 start[6116]: 75335424 | No new notification
Jun 04 15:12:07 vps559055 start[6116]: 66942720 | START : Retrieving all new notifications..
Jun 04 15:12:07 vps559055 start[6116]: 66942720 | No new notification
Jun 04 15:12:08 vps559055 start[6116]: 58550016 | START : Retrieving all new notifications..
Jun 04 15:12:08 vps559055 start[6116]: 58550016 | No new notification
Jun 04 15:12:09 vps559055 start[6116]: 50157312 | START : Retrieving all new notifications..
Jun 04 15:12:09 vps559055 start[6116]: 50157312 | No new notification
Jun 04 15:12:10 vps559055 start[6116]: 41764608 | START : Retrieving all new notifications..
Jun 04 15:12:10 vps559055 start[6116]: 41764608 | No new notification
所有C线程都在同一时间执行(在日志中是同一秒),但是php脚本每秒被执行一次。您知道为什么这些程序的执行方式不同吗?
编辑:可繁殖的例子: 创建一个包含以下内容的php脚本script.php:
$thid = $argv[1]?:null;
echo "php : START PHP SCRIPT ON THREADID $thid\n";
for($i = 0; $i < 3000000; $i++); // work ..
echo "php : END PHP SCRIPT ON THREADID $thid\n";
exit ;
创建一个包含上面代码的main.c文件,然后进行编译:
gcc main.c -o start -lpthread
运行./start
时,所有内容均按例外输出:
[SERVICE] start php script on thread 861141248
php : START PHP SCRIPT ON THREADID 861141248
php : END PHP SCRIPT ON THREADID 861141248
[SERVICE] end of script on thread 861141248
[SERVICE] start php script on thread 939526400
php : START PHP SCRIPT ON THREADID 939526400
php : END PHP SCRIPT ON THREADID 939526400
[SERVICE] end of script on thread 939526400
现在使用此配置文件创建systemd服务:
Description=My Service
After=network-online.target
[Service]
Type=simple
ExecStart=/path/to/c/program /path/to/php/script
Restart=on-failure
# Configures the time to wait before service is stopped forcefully.
TimeoutStopSec=300
[Install]
WantedBy=multi-user.target
输出应该是我获得的:
Jun 05 13:03:00 vps559055 start[4491]: php : START PHP SCRIPT ON THREADID 1259825408
Jun 05 13:03:00 vps559055 start[4491]: php : END PHP SCRIPT ON THREADID 1259825408
// about one second later
Jun 05 13:03:01 vps559055 start[4491]: php : START PHP SCRIPT ON THREADID 1268218112
Jun 05 13:03:01 vps559055 start[4491]: php : END PHP SCRIPT ON THREADID 1268218112
// ...
// same about 50 times
// ...
// then suddenly, i got :
Jun 05 13:03:32 vps559055 start[4491]: [SERVICE] start php script on thread 1175898368
Jun 05 13:03:32 vps559055 start[4491]: [SERVICE] end of script on thread 1175898368
Jun 05 13:03:32 vps559055 start[4491]: [SERVICE] start php script on thread 1184291072
Jun 05 13:03:32 vps559055 start[4491]: [SERVICE] end of script on thread 1184291072
Jun 05 13:03:32 vps559055 start[4491]: [SERVICE] start php script on thread 1192683776
Jun 05 13:03:32 vps559055 start[4491]: [SERVICE] end of script on thread 1192683776
//...
// again about 50 times, IN THE SAME SECOND, all this output
// ...
当程序作为systemd后台服务执行时,为什么输出会变得如此混乱? ...