【问题标题】:Measuring time parallely to looped sigwait in C在 C 中与循环 sigwait 并行测量时间
【发布时间】:2020-12-21 11:33:22
【问题描述】:

我有一个向孩子发送信号的主进程,如下所示:

void handleInputs(query_data *q_data)
{
    char input[DEFAULT_INPUT_SIZE];
    while(1)
    {

        if(fgets(input,DEFAULT_INPUT_SIZE,stdin)==NULL) ERR("FGETS");
        input[strlen(input)-1] = '\0';
        if(!strcmp(input,"exit"))
        {
            kill(0,SIGTERM);
            exit(EXIT_SUCCESS);
        }
        else if(!strcmp(input,"index"))
            kill(0,SIGUSR2);

        else if(!strcmp(input,"status"))
            kill(0,SIGUSR1);    
        else
        {
            char* token = strtok(input, " ");
            if(!token) printf("Wrong input\n");
            else
            {
                if(!strcmp(token,"query"))
                {
                    initializeQueryNumbers(q_data,token);
                    createQueryThread(q_data);
                }
                else printf("Wrong input\n");
            }
            
        }   
    }
}

然后我有一个子进程,它在这样的循环中使用 sigwait 等待信号:

void waitForSignals(data* ch_data)
{
   
    char* pid_directory = strConcat(ch_data->dir, "/.numf_pid");
    int signo;
    for(;;)
    {
        //how to make this block independent to the sigwait
        printf("time elapse: %ld  interval: %d\n",time(NULL)-ch_data->end, ch_data->i);
        if((time(NULL)- ch_data->end)>ch_data->i && ch_data->status ==0)
        {
            printf("Time elapsed from the last indexing > %d\n",ch_data->i);
            createIndexingThread(ch_data);
        }
       //end here

        if(sigwait(&(ch_data->mask), &signo)) ERR("SIGWAIT");
        switch(signo)
        {
            case SIGUSR1:
                if(ch_data->status == 1)
                {
                    printf("Indexing in progress for directory: %s\n",ch_data->dir);
                    printf("Time elapsed: %ld\n", time(NULL)- ch_data->start);
                }
                else printf("No indexing in progress for directory: %s\n",ch_data->dir);
                break;
            case SIGUSR2:
                if(ch_data->status ==0) 
                    createIndexingThread(ch_data);
                else printf("Indexing already in progess for directory: %s\n",ch_data->dir);
                break;
            case SIGTERM:
                if(remove(pid_directory)<0) ERR("REMOVE");
                free(pid_directory);
                if(pthread_cancel(ch_data->tid)==0)
                    printf("Stopped the indexing of directory %s\n",ch_data->dir);
                exit(EXIT_SUCCESS);
        }

        
    }
    if(pthread_join(ch_data->tid,NULL)) ERR("PTHREAD_JOIN");
}

我的子进程创建了一些索引的线程。当从主进程发出 SIGUSR2 信号时(工作正常)或从上次索引经过的时间大于某个用户给定的时间(存储在 ch_data->i 中)时,我想创建这样的线程。然而,现在 cmets 之间的块只有在我从主进程发送一些信号后才会生效。使其并行工作的最佳方法是什么?

【问题讨论】:

  • 如果strlen() 为零或字符串不以换行符结尾,input[strlen(input)-1] = '\0'; 失败。
  • fgets 不是总是在末尾添加 '\n' 吗?我尝试了空输入和“0”,它工作得很好。
  • 关于输入和fgets,尝试输入长度等于或大于DEFAULT_INPUT_SIZE的内容。
  • 它也适用于大输入。这不是我遇到的问题。
  • 我们知道这不是 问题,而是a 问题。您的minimal reproducible example 遇到的无关问题越少,我们为您提供的帮助就越简单。至于fgets 问题,可以说DEFAULT_INPUT_SIZE 2。你给ab\n 作为输入。 fgets 只会读取ainput 的内容将是a\0。使用strlen(input) - 1 将覆盖a 使字符串\0\0。改用strcspn,就像input[strcspn(input, "\n")] = '\0'一样,不管字符串中是否有换行符,它都会做正确的事情。

标签: c time parallel-processing signals posix


【解决方案1】:

如果我理解正确,您是在问如何安排线程操作在在信号时在时间过去自最近一次操作后执行,以先到者为准。

您可以使用sigtimedwait(interesting_sigs, NULL, timeout) 而不是sigwait,根据需要重新计算您的超时

您可能会arm a POSIX timer 来启动操作(或者,也许是给自己发信号)。您需要检查该操作是否最近没有执行,并且您需要适当地重新武装(重新安排)下一个计时器,可能在每个操作结束时。

您可能只是有一个 一个空闲循环的后台线程,它可以完成计时器的工作。有时这些比sigevent 计时器更容易推理。

您可能会合并一个事件驱动的框架,例如 libevent,它知道如何处理超时和信号,而不用担心实现。但是,您可能仍需要重新计算到期时间。

【讨论】:

  • 我设法通过 sigpending 和 sigwait 的组合来做到这一点。还是谢谢
  • @MichałFilipiak,怎么样?这些功能都没有引入计时机制。您想发布自己问题的答案吗?
猜你喜欢
  • 1970-01-01
  • 2019-01-21
  • 1970-01-01
  • 2014-01-23
  • 1970-01-01
  • 1970-01-01
  • 2011-04-23
  • 2021-01-15
  • 2020-03-09
相关资源
最近更新 更多