Yes, there are several ways to do this, among them i/o multiplexing, signal-drive i/o, and asynchronous i/o.
It's likely that for your purposes multiplexing will suffice and it is by far the easiest to implement and get right. Investigate select, poll or epoll There are an abundance of articles, references, and examples available and no shortage of questions/answers here to help you get started. Most common programming languages have a mechanism to expose these services.