You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C语言中不使用多线程中断sleep()函数?

解决ncurses程序中无需多线程立即响应退出按键的问题

你可以通过两种无需多线程的方式实现需求,核心思路是用可中断的等待逻辑替代阻塞的sleep(1),让程序在等待期间仍能监听按键输入:

方案1:使用ncurses内置的超时机制

ncurses的getch()默认是阻塞的,你可以用timeout()函数设置它的超时时间(单位毫秒),这样就能替代sleep(1),同时在等待期间响应按键。

修改后的代码示例:

void run() {
    // 设置getch()最多等待1000毫秒(1秒),超时返回ERR
    timeout(1000);
    
    while (1) {
        for (int i = 0; i < num_things; ++i) {
            int ch = getch();
            if (ch == 'q') {
                // 退出前必须清理ncurses终端环境
                endwin();
                return;
            }
            
            // 不管是超时还是其他按键,都更新内容
            printw("Something");
            refresh();
        }
    }
}
  • 当getch()超时(1秒到了),会返回ERR,程序继续执行内容更新;如果期间按下'q',会立即触发退出逻辑。
  • 退出前务必调用endwin(),否则终端会保持ncurses的特殊模式,导致后续操作异常。

方案2:使用select系统调用监听输入

如果需要更灵活的控制,可以用select()系统调用监听标准输入的可读事件,同时设置1秒超时,完全替代sleep(1)。

修改后的代码示例:

#include <sys/select.h>
#include <unistd.h>

void run() {
    fd_set read_fds;
    struct timeval tv;
    
    while (1) {
        for (int i = 0; i < num_things; ++i) {
            FD_ZERO(&read_fds);
            FD_SET(STDIN_FILENO, &read_fds);
            
            // 设置超时为1秒
            tv.tv_sec = 1;
            tv.tv_usec = 0;
            
            int ret = select(STDIN_FILENO + 1, &read_fds, NULL, NULL, &tv);
            if (ret == -1) {
                perror("select");
                endwin();
                return;
            } else if (ret > 0) {
                // 有输入可读,读取按键判断是否退出
                int ch = getch();
                if (ch == 'q') {
                    endwin();
                    return;
                }
            }
            
            printw("Something");
            refresh();
        }
    }
}
  • select()会等待1秒,期间如果有按键按下,会立即返回并触发按键处理逻辑;超时后则继续执行内容更新。
  • 这种方式不依赖ncurses的内置超时,适合需要同时监听多个输入源的场景。

内容的提问来源于stack exchange,提问作者EwanMe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 07:15:41