I'm designing a Python SSL server that needs to be able to handle up to a few thousand connections per minute. If a client doesn't send any data in a given period of time, the server should close their connection in order to free up resources.
Since I need to check if each connection has expired, would it be more efficient to make the sockets non-blocking and check all the sockets for data in a loop while simultaneously checking if they've timed out, or would it be better to use select() to get sockets that have data and maintain some kind of priority queue ordered by the time data was received on a socket to handle connection timeout?
Alternatively, is there a better method of doing this I haven't thought of, or are there existing libraries I could use that have the features I need?
I'd use a priority queue to keep track of who's been dormant.
Notice, however, that you don't actually need a full-fledged priority queue if you only want to time out connections that have been inactive for a certain fixed amount of time.  You can use a linked list instead:

The linked list stores all of the sockets in sorted order by the last time activity was seen.
When a socket receives data, you update a per-socket "data last seen at" member and move its list entry to the back of the list.
Pass select() the time until the head of the list expires.
At the end of an iteration of your select() loop, you pop off all of the expired list nodes (they're in sorted order) and close the connections.

It's important, if you want sockets to expire at the right time, to use a monotonic clock.  The list might lose its sorted order if the clock happens to go backward at some point.
Connections with timeout: better to set sockets to non-blocking and loop through them or use select() and maintain a priority queue?