linux非阻塞获取命令行输入

不及物动词 其他 173

回复

共3条回复 我来回复
  • fiy的头像
    fiy
    Worktile&PingCode市场小伙伴
    评论

    在Linux中,可以通过使用非阻塞方式获取命令行输入。非阻塞方式是指程序在读取标准输入时不会等待用户输入完成,而是立即返回。这样可以让程序在等待用户输入的同时进行其他的操作。

    要实现非阻塞获取命令行输入,可以使用以下方法:

    1. 使用fcntl()函数设置标准输入为非阻塞模式:
    “`c
    #include
    #include

    int set_nonblocking(int fd) {
    int flags = fcntl(fd, F_GETFL, 0);
    if (flags == -1) {
    return -1;
    }
    return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
    }
    “`
    在程序的初始化部分,可以调用set_nonblocking(STDIN_FILENO)函数将标准输入(STDIN_FILENO)设置为非阻塞模式。

    2. 使用select()函数来检查是否有输入就绪:
    “`c
    #include
    #include

    int main() {
    fd_set rfds;
    struct timeval tv;
    int retval;

    FD_ZERO(&rfds);
    FD_SET(STDIN_FILENO, &rfds);

    tv.tv_sec = 0;
    tv.tv_usec = 0;

    retval = select(STDIN_FILENO + 1, &rfds, NULL, NULL, &tv);
    if (retval == -1) {
    perror(“select()”);
    } else if (retval > 0) {
    if (FD_ISSET(STDIN_FILENO, &rfds)) {
    char buf[256];
    int numRead = read(STDIN_FILENO, buf, sizeof(buf));
    if (numRead == -1) {
    perror(“read()”);
    } else {
    // 处理读取到的输入
    }
    }
    }

    // 其他操作
    return 0;
    }
    “`
    在主循环中,使用select()函数来检查是否有输入就绪。如果有输入就绪,则通过read()函数读取输入。

    以上就是在Linux中实现非阻塞获取命令行输入的方法。通过设置标准输入为非阻塞模式,并使用select()函数来检查是否有输入就绪,程序可以在等待用户输入的同时进行其他操作。

    2年前 0条评论
  • 不及物动词的头像
    不及物动词
    这个人很懒,什么都没有留下~
    评论

    在Linux系统中,可以使用非阻塞方式获取命令行输入。这种方式允许程序在读取输入时不会阻塞,可以继续执行其他操作。

    以下是一种使用非阻塞方式获取命令行输入的方法:

    1. 使用非阻塞I/O函数:
    在Linux系统中,可以使用非阻塞的I/O函数,如`fcntl()`和`select()`函数来实现非阻塞方式获取命令行输入。首先,使用`fcntl()`函数将标准输入(STDIN_FILENO)的文件描述符设置为非阻塞模式。示例代码如下:

    “`c
    #include
    #include
    #include
    #include

    int main() {
    // 设置标准输入为非阻塞模式
    int flags = fcntl(STDIN_FILENO, F_GETFL, 0);
    flags |= O_NONBLOCK;
    fcntl(STDIN_FILENO, F_SETFL, flags);

    // 循环读取输入
    while(1) {
    char input[256] = {0};
    int ret = read(STDIN_FILENO, input, sizeof(input));
    if(ret > 0) {
    printf(“输入:%s\n”, input);
    }
    usleep(1000);
    }

    return 0;
    }
    “`

    2. 使用select函数实现非阻塞读取:
    `select()`函数可以监视文件描述符的可读状态,当可读时执行相应操作。使用`select()`函数的一个优点是,可以同时监视多个文件描述符,例如标准输入和其他文件描述符。示例代码如下:

    “`c
    #include
    #include
    #include
    #include

    int main() {
    fd_set readfds;
    struct timeval timeout;

    // 循环读取输入
    while (1) {
    FD_ZERO(&readfds);
    FD_SET(STDIN_FILENO, &readfds);

    timeout.tv_sec = 0;
    timeout.tv_usec = 1000;

    int ret = select(STDIN_FILENO + 1, &readfds, NULL, NULL, &timeout);
    if (ret > 0) {
    char input[256] = {0};
    if(FD_ISSET(STDIN_FILENO, &readfds)){
    fgets(input, sizeof(input), stdin);
    printf(“输入:%s\n”, input);
    }
    }
    }

    return 0;
    }
    “`

    3. 使用轮询方式读取输入:
    另一种方式是使用轮询方式读取命令行输入。在循环中使用`kbhit()`和`getch()`函数来判断是否有输入,并进行相应处理。`kbhit()`函数用于检测是否有按键输入,`getch()`函数用于获取按下的键值。示例代码如下:

    “`c
    #include
    #include
    #include
    #include
    #include

    int kbhit(void) {
    struct timeval tv = {0, 0};
    fd_set rdfs;
    FD_ZERO(&rdfs);
    FD_SET(STDIN_FILENO, &rdfs);
    return select(STDIN_FILENO + 1, &rdfs, NULL, NULL, &tv);
    }

    int getch(void) {
    int c = 0;
    struct termios org_opts, new_opts;
    tcgetattr(STDIN_FILENO, &org_opts);
    new_opts = org_opts;
    new_opts.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL | ICRNL);
    tcsetattr(STDIN_FILENO, TCSANOW, &new_opts);
    c = getchar();
    tcsetattr(STDIN_FILENO, TCSANOW, &org_opts);
    return c;
    }

    int main() {
    // 循环读取输入
    while (1) {
    if (kbhit()) {
    int c = getch();
    printf(“输入:%c\n”, c);
    }
    }

    return 0;
    }
    “`

    4. 使用线程处理输入:
    另一种方式是创建一个单独的线程来处理命令行输入。在新线程中使用阻塞方式读取输入,然后将输入传递给主线程进行处理。这种方式可以避免主线程被阻塞,并能同时处理其他任务。

    “`c
    #include
    #include
    #include
    #include

    void* input_thread(void* arg) {
    char input[256] = {0};
    while (1) {
    fgets(input, sizeof(input), stdin);
    printf(“输入:%s”, input);
    }
    return NULL;
    }

    int main() {
    pthread_t thread;
    pthread_create(&thread, NULL, &input_thread, NULL);

    // 循环执行其他任务
    while (1) {
    // 执行其他任务
    }

    pthread_join(thread, NULL);

    return 0;
    }
    “`

    5. 使用异步I/O(AIO):
    异步I/O是Linux提供的一种非阻塞读写数据的机制,可以使用`aio_read()`或者`aio_suspend()`函数实现非阻塞方式获取命令行输入。

    “`c
    #include
    #include
    #include
    #include
    #include

    #define BUF_SIZE 256

    int main() {
    char buffer[BUF_SIZE] = {0};
    struct aiocb aiocb;

    // 打开标准输入文件
    int fd = open(“/dev/stdin”, O_RDONLY);
    if (fd == -1) {
    perror(“打开文件失败”);
    exit(1);
    }

    // 初始化异步I/O结构体
    aiocb.aio_fildes = fd;
    aiocb.aio_buf = buffer;
    aiocb.aio_nbytes = BUF_SIZE;
    aiocb.aio_offset = 0;

    // 开始异步读取
    aio_read(&aiocb);

    // 循环检查异步读取状态
    while (1) {
    if (aio_error(&aiocb) == EINPROGRESS) {
    continue;
    }
    if (aio_return(&aiocb) > 0) {
    printf(“输入:%s\n”, buffer);
    }
    aio_read(&aiocb);
    }

    // 关闭文件
    close(fd);

    return 0;
    }
    “`

    通过以上方法,可以实现在Linux系统中以非阻塞方式获取命令行输入。具体方法的选择可以根据需求和应用场景来确定。

    2年前 0条评论
  • worktile的头像
    worktile
    Worktile官方账号
    评论

    在Linux中,可以使用非阻塞方式获取命令行输入,即在没有用户输入时不会等待。这在某些场景下十分有用,例如在程序运行期间需要同时处理其他任务,但仍然需要检查命令行输入。

    为了实现非阻塞获取命令行输入,可以使用以下方法:

    1. 使用非标准库函数:
    – 使用`fcntl`函数设置文件描述符属性为非阻塞模式。可以通过以下代码实现:
    “`c
    #include
    #include
    #include

    int main()
    {
    int flags = fcntl(0, F_GETFL); // 获取标准输入描述符的属性
    flags |= O_NONBLOCK; // 设置为非阻塞模式
    fcntl(0, F_SETFL, flags); // 应用设置

    char buffer[1024];
    int bytesRead = read(0, buffer, sizeof(buffer)); // 读取输入
    if (bytesRead > 0)
    {
    buffer[bytesRead] = ‘\0’;
    printf(“Input: %s\n”, buffer);
    }
    else if (bytesRead == 0)
    {
    printf(“No input received\n”);
    }
    else if (bytesRead == -1)
    {
    printf(“No input available\n”);
    }

    return 0;
    }
    “`
    上述代码通过将标准输入描述符的属性设置为非阻塞模式,并使用`read`函数进行读取输入。如果有输入,则打印输入;如果没有输入,则打印相应的消息。

    2. 使用`select`函数:
    – 使用`select`函数来监听文件描述符的可读状态。可以通过以下代码实现:
    “`c
    #include
    #include
    #include
    #include

    int main()
    {
    fd_set readfds;
    FD_ZERO(&readfds);
    FD_SET(0, &readfds); // 将标准输入描述符添加到监控集合

    struct timeval timeout;
    timeout.tv_sec = 0;
    timeout.tv_usec = 0; // 设置超时为0,即立即返回

    int ready = select(1, &readfds, NULL, NULL, &timeout); // 监听标准输入描述符

    if (ready == -1)
    {
    perror(“select error”);
    exit(1);
    }
    else if (ready > 0)
    {
    char buffer[1024];
    int bytesRead = read(0, buffer, sizeof(buffer)); // 读取输入
    if (bytesRead > 0)
    {
    buffer[bytesRead] = ‘\0’;
    printf(“Input: %s\n”, buffer);
    }
    }
    else if (ready == 0)
    {
    printf(“No input received\n”);
    }

    return 0;
    }
    “`
    上述代码使用`select`函数监听标准输入描述符的可读状态。如果有输入,则使用`read`函数读取输入并打印;如果没有输入,则打印相应的消息。

    3. 使用`poll`函数:
    – 使用`poll`函数来监听文件描述符的可读状态。可以通过以下代码实现:
    “`c
    #include
    #include
    #include
    #include

    int main()
    {
    struct pollfd fds[1];
    fds[0].fd = 0; // 标准输入描述符
    fds[0].events = POLLIN; // 监听可读事件

    int ready = poll(fds, 1, 0); // 监听标准输入描述符

    if (ready == -1)
    {
    perror(“poll error”);
    exit(1);
    }
    else if (ready > 0)
    {
    char buffer[1024];
    int bytesRead = read(0, buffer, sizeof(buffer)); // 读取输入
    if (bytesRead > 0)
    {
    buffer[bytesRead] = ‘\0’;
    printf(“Input: %s\n”, buffer);
    }
    }
    else if (ready == 0)
    {
    printf(“No input received\n”);
    }

    return 0;
    }
    “`
    上述代码使用`poll`函数监听标准输入描述符的可读事件。如果有输入,则使用`read`函数读取输入并打印;如果没有输入,则打印相应的消息。

    通过上述方法,可以实现Linux中非阻塞获取命令行输入的功能,使程序能够同时处理其他任务而不会因等待用户输入而阻塞。

    2年前 0条评论
注册PingCode 在线客服
站长微信
站长微信
电话联系

400-800-1024

工作日9:30-21:00在线

分享本页
返回顶部