C:暂停system()调用

智商

尝试暂停执行system()呼叫时,C语言出现问题

线程重复调用某个应用程序(例如某个基准)。每当收到信号时SIGUSR1,暂停执行并在接收时恢复SIGUSR2

来源看起来像这样:

#include <signal.h>
#include <pthread.h>

void* run_app(sigset_t* signalsBetweenControllerandLoad)
{
    /* assign handler */
    signal(SIGUSR1, pausesignal_handler)
    signal(SIGUSR2, pausesignal_handler)
    pthread_sigmask(SIG_UNBLOCK, signalsBetweenControllerandLoad, NULL))

    /* call application repeatedly */
    while(1) {
        system(SOMECOMMAND);
    }

    return(0);
}

static void pausesignal_handler(int signo)
{
    int caughtSignal;
    caughtSignal = 0;

    /* when SIGUSR1 is received, wait until SIGUSR2 to continue execution */
    if (signo == SIGUSR1) {
        signal(signo, pausesignal_handler);

        while (caughtSignal != SIGUSR2) {
            sigwait (signalsBetweenControllerandLoad, &caughtSignal);
        }
    }
}

当我使用一些命令(例如下面的for循环进行一些计算)而不是system(SOMECOMMAND)这段代码有效时。但是,当处理程序处于活动状态时,不会暂停system()调用的程序。

int i;
for(i=0;i<10;i++) {
    sleep(1);
    printf("Just a text");
}

有没有一种方法可以通过使用线程信号来暂停system()命令的执行?甚至还有一种方法可以停止系统调用的应用程序,而无需等待程序完成?

提前非常感谢您!

智商

在@rici的帮助下,我想向您介绍我的(缩短的)结果代码。再次感谢您。简而言之,该代码会派生一个新进程(fork),并在其中执行命令exec然后父捕获用户定义的信号SIGNAL_PAUSESIGNAL_RESUME相应并转发信号到叉形子。每当命令完成时-被捕获waitpid-父级再次分叉并重新启动加载。这将重复进行,直到SIGNAL_STOP被发送到孩子得到aSIGINT并被取消的位置。

#include <pthread.h>
#include <signal.h>
#include <stdio.h>

#define SIGNAL_PAUSE (SIGUSR1)
#define SIGNAL_RESUME (SIGUSR2)
#define SIGNAL_STOP (SIGSYS)

/* File scoped functions */
static void pausesignal_handler(int signo);
static void stopsignal_handler(int signo);
void send_signal_to_load_child(int signo);

/*Set file scope variables as handlers can only have signal-number as argument */
sigset_t* signalsBetweenControllerandLoad;
int restart_benchmark;
pid_t child_pid;

void* Load(char* load_arguments[MAX_NR_LOAD_ARGS], sigset_t* signalsToCatch) {
    int load_ID;
    pid_t p;

    signalsBetweenControllerandLoad = signalsToCatch;

    /* set signal handlers to catch signals from controller */
    signal(SIGNAL_PAUSE, pausesignal_handler)
    signal(SIGNAL_RESUME, pausesignal_handler)
    signal(SIGNAL_STOP, stopsignal_handler)
    pthread_sigmask(SIG_UNBLOCK, signalsBetweenControllerandLoad[load_ID], NULL)

    /* Keep restarting benchmark until Stop signal was received */
    restart_benchmark[load_ID] = 1;

    /* execute benchmark, repeat until stop signal received */
    while(restart_benchmark[load_ID])
    {
        if (child_pid == 0) {
            if ((p = fork()) == 0) {
                execv(load_arguments[0],load_arguments);
                exit(0);
            }
        }

        /* Parent process: Wait until child with benchmark finished and restart it */
        if (p>0) {
            child_pid = p;  /* Make PID available for helper functions */
            wait(child_pid);        /* Wait until child finished */
            child_pid = 0;  /* Reset PID when benchmark finished */
        }
    }

    return(0);
}

static void pausesignal_handler(int signo) {
    static double elapsedTime;
    int caughtSignal;
    caughtSignal = 0;

    if (signo == SIGNAL_PAUSE) {
        send_signal_to_load_child(SIGSTOP);
        printf("Load Paused, waiting for resume signal\n");

        while (restart_benchmark == 1 && caughtSignal != SIGNAL_RESUME) {
            sigwait (signalsBetweenControllerandLoad, &caughtSignal);
            if (caughtSignal == SIGNAL_STOP) {
                printf("Load caught stop signal when waiting for resume\n");
                stopsignal_handler(caughtSignal);
            } else if (caughtSignal != SIGNAL_RESUME) {
                printf("Load caught signal %d which is not Resume (%d), keep waiting...\n",caughtSignal,SIGNAL_RESUME);
            }
        }
        if (restart_benchmark[load_ID]) {
            send_signal_to_load_child(SIGCONT, load_ID);
            printf("Load resumed\n");
        }
    } else {
        printf("Load caught unexpected signal %d.\n",signo);
    }
    /* reassign signals for compatibility reasons */
    signal(SIGNAL_PAUSE, pausesignal_handler);
    signal(SIGNAL_RESUME, pausesignal_handler);
}

static void stopsignal_handler(int signo) {
    double elapsedTime;
    signal(SIGNAL_STOP, stopsignal_handler);
    if (signo == SIGNAL_STOP) {
        restart_benchmark = 0;
        send_signal_to_load_child(SIGINT);
        printf("Load stopped.\n");
    } else {
        printf("catched unexpected stop-signal %d\n",signo);
    }
}

void send_signal_to_load_child(int signo) {
    int dest_pid;
    dest_pid = child_pid;
    printf("Error sending %d to Child: PID not set.\n",signo);
    kill(dest_pid, signo);
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

从c调用system()

来自分类Dev

C ++:重复调用system()

来自分类Dev

system()中的变量调用C ++

来自分类Dev

在C中利用system()调用

来自分类Dev

调用暂停后,NSProgress恢复

来自分类Dev

在C ++中查看system()调用的输出

来自分类Dev

C 程序中的 system() 调用安全吗?

来自分类Dev

如何从Libgdx动态调用覆盖暂停方法?

来自分类Dev

在RxJava中调用onNext之间暂停

来自分类Dev

暂停被调用函数几秒钟

来自分类Dev

在活动/片段中调用多个暂停函数

来自分类Dev

在状态8中调用MediaPlayer暂停

来自分类Dev

Powershell 调用表达式暂停

来自分类Dev

在C / C ++中可继承system()调用的功能

来自分类Dev

从 c# 项目 System.AccessViolationException 调用 c++ char*

来自分类Dev

C#暂停程序执行

来自分类Dev

Java返回码未通过C ++ system()调用正确记录

来自分类Dev

返回从本地C ++调用编组的System :: String时崩溃

来自分类Dev

在C ++中调用system()时出现问题

来自分类Dev

大型数组的P / Invoke调用上的c#System.ExecutionEngineError

来自分类Dev

在C ++中使用system()调用其他程序

来自分类Dev

C 生成正确的 shell 命令,但 system() 调用返回意外值

来自分类Dev

在cocos2dx的暂停菜单中暂停时无法调用方法

来自分类Dev

LibGDX-从未调用的暂停和处理方法

来自分类Dev

暂停应用程序时不调用OnNavigatedFrom

来自分类Dev

调用本机代码时,JVM是否会暂停?

来自分类Dev

拖动窗口时未调用Libgdx暂停/恢复(Windows)

来自分类Dev

Mediaplayer:在状态1中调用暂停-Android Eclipse

来自分类Dev

暂停大量的AJAX调用,多个数据集