每 20 秒打印一次消息的信号(C 多线程程序)

Posted

技术标签:

【中文标题】每 20 秒打印一次消息的信号(C 多线程程序)【英文标题】:Signal to print message every 20 seconds (C Multithreaded program) 【发布时间】:2015-12-06 03:55:16 【问题描述】:

我试图在多线程程序中每 20 秒打印一条消息。我有一个有两个线程的服务器。一个线程等待传入的连接,并在连接时为客户端创建一个新线程。

我看过这个:C: SIGALRM - alarm to display message every second 但是我的代码,我不确定我会把循环放在哪里。我不允许创建新线程或使用sleep()sleep() 的任何变体。

服务器接受线程的代码:

while((csock = accept(sock, (struct sockaddr *) &theClient, (socklen_t *) &cl)))

        pthread_t newClient;
        new_sock = malloc(sizeof(socket_t));
        *new_sock = csock;
        pthread_create(&newClient, NULL, getInput, (void *) new_sock)

另一个线程只是处理客户端的输入。我尝试将循环放在上面的循环中,但它从不接受新的连接。

我该怎么做呢?任何帮助将不胜感激。

【问题讨论】:

一个线程在等待传入连接时在做什么?这似乎是处理这个问题的地方。 那里的线程是等待传入连接的线程。不是在等待accept() 方法吗?我认为它在等待连接时不能做任何其他事情。 看看setitimertimer_create+timer_settime。两者都可以用来设置一个计时器,可以通过一个信号来处理到期。 好的,我会调查的。谢谢。 【参考方案1】:

您的问题目前似乎是 accept() 正在阻塞线程,直到有新连接进入;因此你不能打印任何东西。

您可以在循环中使用非阻塞accept() 来检查连接,并在同一个循环中等待20 秒过去。请注意,这是非常低效的,因为此循环不会停止;它使用 1 个 cpu 核心的 100%。

// sock is listening
fcntl(sock,F_SETFD,O_NONBLOCK);

time_t tm = time(); // Unix timestamp, in seconds.

while(true) 
  csock = accept(sock, (sockaddr*)&theClient, (socklen_t*)&cl);
  if (csock==-1) 
    if (errno==EAGAIN || errno==EWOULDBLOCK); // No connection at the
                                              // moment, we need to try
                                              // again later.
    else break; // Some other error occurred
  
  else  // If it is connected
    pthread_t newClient;
    new_sock = malloc(sizeof(socket_t));
    *new_sock = csock;
    pthread_create(&newClient,NULL,getInput,(void*)new_sock);
  

  if (time()-tm>=20)  // At least 20 seconds have elapsed since
                       // last message.
    printf("Hello World!!\n");
    tm = time(); // Start waiting for another 20 seconds.
  

使用 select() 来等待新的连接会更有效率 - 你也可以设置一个过期的超时,这样你就可以打印你的消息了

编辑:您不想使用信号,因为正如您链接的文章中所说,您不能在信号处理程序内部使用printf。 如果您使用信号处理程序设置标志,您将无法读取该标志,除非您使用非阻塞的 accept()(因为否则 accept() 可能会阻塞一分钟但没有任何输出)。

【讨论】:

除了printf,还有其他输出到终端的方式。 write 例如是异步安全的,可用于写入标准输出。

以上是关于每 20 秒打印一次消息的信号(C 多线程程序)的主要内容,如果未能解决你的问题,请参考以下文章

linux c++多线程,创建两个子线程,主线程有个循环,循环内需要从两个子线程中获取数据,然后计算结果。

计算多线程应用程序中的 CPU、内存、网络使用情况

多线程 & 信号量 & 事件

qt中如何实现多线程?

qt中如何实现多线程?

POSIX(Linux多线程)使用信号量三个线程顺序打印十次123