首页 > 代码库 > linux下模拟按键kbhit(),检测按键终止while(1)死循环

linux下模拟按键kbhit(),检测按键终止while(1)死循环

如何通过另外一个事件来控制while循环以及在必要的时候使用按键控制while死循环

1、设置一个循环标志。主进程中进行循环并且在每次循环中检查循环标志决定是否继续,线程中检测按键输入后改变该标志


2、主进程中进行按键检测,线程用于循环操作,主进程检测到按键后关闭循环线程


3、在循环中对键盘缓冲区进行扫描,用于判断是否有按键信息


这里我们不使用多线程的机制,直接来检测按键的信息来控制while循环,在有按键按下的时候终止while循环,即在扫描按键的时候不阻塞while循环事件。不废话直接上代码。

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <termios.h>
#include <termio.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <errno.h>
#include <regex.h>
#include <sys/time.h>

using namespace std;
static struct termio term_orig;
static int kbdflgs;
<span style="color: rgb(0, 130, 0); font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; font-size: 13.63636302947998px; line-height: 15.397727012634277px; white-space: nowrap;">/* 判断是否有按键按下 */</span>
int kbhit(void)
{
	struct timeval tv;
	struct termios old_termios, new_termios;
	int error;
	int count = 0;
	tcgetattr(0, &old_termios);
	new_termios = old_termios;
	new_termios.c_lflag &= ~ICANON;
	new_termios.c_lflag &= ~ECHO;
	new_termios.c_cc[VMIN] = 1;
	new_termios.c_cc[VTIME] = 0;
	error = tcsetattr(0, TCSANOW, &new_termios);
	tv.tv_sec = 0;
	tv.tv_usec = 100;
	select(1, NULL, NULL, NULL, &tv);
	error += ioctl(0, FIONREAD, &count);
	error += tcsetattr(0, TCSANOW, &old_termios);
	return error == 0 ? count : -1;
}

/**
* system_mode
* reset the system to what it was before input_mode was
* called
*/
void system_mode(void)
{
	if (ioctl(0, TCSETA, &term_orig) == -1) {
		return;
	}
	fcntl(0, F_SETFL, kbdflgs);
}
/**
* input_mode
* set the system into raw mode for keyboard i/o
* returns  0 - error
*          1 - no error
*/
int input_mode(void)
{
	struct termio term;
	if (ioctl(0, TCGETA, &term) == -1) {
		return 0;
	}

	(void)ioctl(0, TCGETA, &term_orig);
	term.c_iflag = 0;
	term.c_oflag = 0;
	term.c_lflag = 0;
	term.c_cc[VMIN] = 1;
	term.c_cc[VTIME] = 0;
	if (ioctl(0, TCSETA, &term) == -1) {
		return 0;
	}
	kbdflgs = fcntl(0, F_GETFL, 0);
	int flags = fcntl(0, F_GETFL);
	flags &= ~O_NDELAY;
	fcntl(0, F_SETFL, flags);
	return 1;
}

/**
* getch
* read a single character from the keyboard without echo
* returns: the keypress character
*/
int getch(void)
{
	unsigned char ch;
	input_mode();
	while (read(0, &ch, 1) != 1);
	system_mode();
	return (ch);
}

int main()
{
	while (!kbhit())
	{
		cout << "chenxun is a sb" << endl;
	}
}


linux下模拟按键kbhit(),检测按键终止while(1)死循环