No, the SELECT statement you show does not lock any rows. It's a non-locking read, because it does not include a locking clause (FOR UPDATE or FOR SHARE).
Even if you do use a locking read, you can still get a deadlock, because concurrent transactions may request locks in an interleaved fashion, and end up waiting for each other.
Read https://dev.mysql.com/doc/refman/en/innodb-locking-reads.html for more details on locking reads.
Basically, deadlocks may happen if concurrent sessions are doing updates against the same table.
You have these options to prevent deadlocks:
Do not allow updates from concurrent sessions. Do updates only from one session at a time.
Use pessimistic table locks or user locks, to ensure only one session at a time can run updates. But this tends to create a bottleneck if sessions are queued up waiting for the single lock.
Other than that, just write your client code to catch deadlock exceptions and retry.
Re your comment:
I can't tell from your queries what is the table definition or the EXPLAIN strategy for the UPDATE. It could lock non-atomically especially if the table has multiple unique keys. Or it could lock without the use of an index, so it has to fall back to locking every row in the table. Or the index it chooses could vary based on the optimizer's decision each time you run the UPDATE.
The bottom line is that it's hard to prevent deadlocks if you run concurrent sessions. You should always code defensively. That is, you should assume deadlocks will happen, and write code to handle them with retries.