gpt4 book ai didi

需要处理查询时 C 秒滴答作响?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:07:22 25 4
gpt4 key购买 nike

我们在下面有一个代码,它每秒都在滴答作响,它工作得很好。当我们有//select 和 insert 查询需要处理时,问题就开始了,我们注意到每一秒都有 1 到 10 秒的时间间隔。因此,我们实际上错过了一些要完成的处理。知道如何克服这个吗?是不是我们需要在每一秒创建一个单独的线程是吗?谢谢。

void * reader_thread (void * arg) {
while (1) {
if (flag) {
struct timeval tv;
char timeBuf[10],secondBuf1[100],queryBuf1[500],queryBuf2[500];
char buff[20] = {0};
gettimeofday (&tv, NULL);
//fprintf (stderr, "[%d.%06d] Flag set to 1 on ", tv.tv_sec, tv.tv_usec);
tv.tv_sec -= 5;
strftime(buff, 20, "%Y-%m-%d %H:%M:%S", localtime(&tv.tv_sec));
printf("\nTime is %s", buff);

//select and insert queries

fprintf (stderr, " %s\n", buff);
flag = 0;
}
usleep (100); // will skew the processing but not signal delivery
}
return NULL;
}

void callback (int sig) {
flag = 1; // this is the only thing the callback does
}

int main () {
timer_t tid = 0;
pthread_t thread;
struct itimerspec it;
char *localServer = "localhost", *remoteServer = "localhost";
char *localUser = "user1", *remoteUser = "user2";
char *localPassword = "****", *remotePassword = "*****";
char *localDatabase = "db1", *remoteDatabase = "db1";
localConn = mysql_init(NULL), remoteConn = mysql_init(NULL);
if (!mysql_real_connect(localConn, localServer,
localUser, localPassword, localDatabase, 0, NULL, 0)) {
fprintf(stderr, "%s\n", mysql_error(localConn));
exit(1);
}



pthread_create (&thread, NULL, reader_thread, NULL);

signal (SIGALRM, callback);

it.it_value.tv_sec = 1;
it.it_value.tv_nsec = 0;
it.it_interval.tv_sec = 1;
it.it_interval.tv_nsec = 0;
timer_create (CLOCK_REALTIME, NULL, &tid);
timer_settime (tid, 0, &it, NULL);

while (1) sleep (100);
return 0;
}

编辑代码。

sigset_t sigset;
sigfillset(&sigset);

if (pthread_sigmask(
SIG_BLOCK,
&sigset,
NULL))
{
perror("pthread_sigmask");
}

pthread_create (&thread, NULL, reader_thread, NULL);

//sigset_t sigset;
//sigemptyset(&sigset);
sigaddset(&sigset, SIGALRM);

if (pthread_sigmask(
SIG_UNBLOCK,
&sigset,
NULL))
{
perror("pthread_sigmask");
}

最佳答案

您可能希望对此进行一些不同的设置:

1 在生成任何线程之前使用pthread_sigmask() 让应用程序忽略所有信号。然后,此行为将由之后创建的任何线程继承,并使它们不会吃掉任何信号,因为只有主线程会处理它们(请参见下面的第 2 步)。

2 创建所有线程后再次使用pthread_sigmask()让主线程接收SIGALRM并使用sigaction() (而不是 signal();另请参阅我对 OP 的评论)为 SIGALRM 设置信号处理程序。

3 为每个线程声明一个标志。目前,重置标志的线程可能会在另一个线程启动之前执行此操作。


如果主线程不必再做任何事情(或者您不介意生成另一个线程):或者使用 sigaction() 安装信号处理程序(如上面第 2 步所述)你可以使用类似 do { int sig = sigwaitinfo(...); ... } while (1); 从队列中提取信号并设置用于触发查询开始的标志。


更新:

有关如何使用 pthread_sigmask() 来阻止调用线程的所有 信号的示例:

sigset_t sigset;
sigfillset(&sigset);

if (pthread_sigmask(
SIG_BLOCK,
&sigset,
NULL))
{
perror("pthread_sigmask");
}

有关如何使用 pthread_sigmask() 为调用线程解锁 SIGALRM 的示例:

sigset_t sigset;
sigemptyset(&sigset);
sigaddset(&sigset, SIGALRM);

if (pthread_sigmask(
SIG_UNBLOCK,
&sigset,
NULL))
{
perror("pthread_sigmask");
}

有关 pthread_sigmask() 的更多详细信息,请参阅 man pthread_sigmask()

关于需要处理查询时 C 秒滴答作响?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11481274/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com