depends on what you are doing. how did that value get assigned? If the value can potentially be out of date for the current thread, its not safe. It will run and execute, but it will use the wrong value. So you don't need a mutex but you need to be sure that either an out of date value is OK OR that you have the latest copy (see, volatile keyword, but that is inefficient so use only when necessary). Mutex is needed if you write to the same thing at the same time, or if changing something in one thread could break another (like reading from same file variable in 2 threads). A mutex can solve the sync problem as well, and it is also a performance hit, but you are using it for something slightly off its intended purpose (not too far off, but a little).
how about a practical example:
example 1, you want to print your vehicle's current gps location on the screen.
if your thread that prints is off from the thread that reads the hardware, its OK: the user won't know the difference between the last read and the not yet seen current value.
example 2: you use the gps value to steer the vehicle. Now the up to date value is critical, and the last value just won't do.
and if so, is it then safe to have just one thread write to it (without locking it) as long as every other thread only reads it?
No. You have no guarantee that halfway through writing, some other thread won't come in and read it while it's in some weird half-way state. Some types will suffer this more than others.
However, if it's an atomic variable, that's not a problem.
If you want to learn more about multithreading you can look at this, it is a pretty in-depth and short explanation of all the things you should be aware of. https://randu.org/tutorials/threads/
And also the book "Concurrency in Action" is also very good book that shows how to use C++'s thread library, and shows a lot of structures and use cases.
And note that multithreading isn't a good idea if you haven't gotten a good understanding of the fundamentals of C++, and how large projects in C++ look like, since beginners usually start off programming without knowing what they are doing, and write code without doing any research on how to do it in a more sane way, and multithreading is not something that works well with code pulled out of your ass. Many structures in multithreaded code are very consistent (structurally) between many codebases, similar to the Gang of Four structures and other idioms since misusing multithreading can easily make your code very coupled and very ugly, if used naively.
It's obviously a good tool for certain scenarios, like having a loading screen for a graphical project while not having a "not responding" message if you naively make a single threaded project, but you will find that in many cases it isn't worth it because you are breaking the KISS rule, which even large scale projects try to follow. But multithreading should not be used for performance, for a inexperienced programmer because there is still much to learn about optimized single threaded code.
However, if it's an atomic variable, that's not a problem.
^^^^
That is also very important. Atomic means 'will fit in a single cpu register' for a simple definition. Imagine you were dealing with a string. Imagine it was 1/2 of the way through its update when you read it. If it was hello world and you changed it to goodbye cruel world, you might get goodo world. I didnt think of it as I had integers on my mind.