我试图在多线程程序中每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)
}
另一个线程只是处理客户端的输入。我尝试将循环放在上面的循环中,但之后它永远不会接受新的连接。
我该怎么做呢?任何帮助将不胜感激。
答案 0 :(得分:1)
你的问题似乎是,在新连接进入之前,accept()正在阻塞线程;因此你无法打印任何东西。
您可以在循环中使用非阻塞accept()来检查连接,并在同一循环中等待,直到20秒过去。请注意,这是非常低效的,因为这个循环不会停止;它使用100%的1 cpu核心。
// 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()可能会阻塞一分钟但没有打印)。