I wouldn't say that's correct. In terms of threading...
POX itself doesn't use threads for performance reasons. There's hardly such a thing as threads for performance in Python. POX may use a couple threads in some places for design/organization/convenience reasons. Indeed, it almost certainly uses at least one extra one (for IO, as mentioned) unless you're using
--unthreaded-sh. This alters performance characteristics (e.g., the change in latency you observed), but that's not why it was done this way. It was both a structural/design decision and it can be convenient in a number of cases (e.g., using POX with foreign event loops). But in lots of cases isn't really necessary (hence the ability to turn it off).
But that's just POX itself. When you write components, there's nothing to force you to use threads or not to use them. Again, Python is likely to be the limiting factor here: using threads will generally not buy you computational performance (though it may buy you convenience or let you structure things in a way you like or avoid blocking with blocking APIs, etc.).
POX does have some support for writing "cooperative tasks" via recoco, which is its own cooperative scheduler and "cooperative syscall" layer. This was a design point inspired by NOX. These are sort of like "green threads" or whatever you want to call them. The OpenFlow event handlers in POX are all called from such a cooperative task. This scheduler and the tasks in it are all run from a single actual thread. (This is why POX normally runs on two threads -- one for IO and another one for cooperative tasks;
--unthreaded-sh jams the two of them together onto a single thread. I think if you want to be technical about it, those both normally run on new threads and the main thread just goes to sleep, so there's actually normally three? It's been a while...)
In terms of centralization...
POX is not limited to centralized architectures. None of the sample POX apps have any explicit distribution, but that doesn't mean you can't do it using POX. Indeed, parts of it may be at least slightly useful for implementing distribution. Here I'm specifically thinking that I believe there was a DHT implemented atop the POX messenger component at some point (and I was also thinking that the fangtooth branch had some support for gRPC, but looking at the repo, I guess that hasn't been pushed... yet?). But there's some good argumentation that in many cases, you probably shouldn't write explicitly distributed controllers even if you want a distributed controller -- see the SCL paper by Panda et al.