POSIX has added _l variants taking a locale_t argument to all the relevant string functions. I can see how per-thread state would be convenient, but it's not a comprehensive solution. With the _l variants you can write your own wrappers that pass a per-thread locale_t object.