wxExecute must not be used from anything but the main thread. First, it will rise an assertion if you try to, and second, wxExecute calls wxYield() at the most impossible of times, possibly causing recursive Yields.
wxExecute always runs on processes, but this is really not the reason why it is so inefficient. The main reason why it is so bad is that you must regularly Yield or you will never get anything from the pipe. The pipe will fill up and the child process will block. Consequently, your application will block, too, waiting for the child to die.
There are two modes of operation for wxExecute, one is while(!done){wxYield();} - this is what wxExecute does internally when running synchronously, it is *horribly* inefficient. The other way (the recommended way for asynchronous execution, and also the way it is done in code::blocks) is to use a wxTimer, which wastes less CPU, but means that no matter what you do, the Timer's minimum latency (around 50ms) plus the time needed to pass messages through the wx message queue (50-250ms?) always add to the execution time of your process. If you spawn off 200 processes, this can be quite a few seconds. There is nothing you can do, though, it is like this by design.
Apart from wxExecute, there is no way to run a command in a thread, either. It obviously has to be process (except if you load the executable image like a dll and do some hokuspokus maybe, but let's not even think about that...). However since the question was about Linux originally, process and thread is not really a different thing.
I would also advocate to be really gratious with threads (i.e. have several thread pools, and keep them sleeping rather than ending them). Thread scheduling is O(0) under Linux, and although the Windows scheduler sucks, it is still better to keep a few threads sleeping than spawn new ones regularly, as this is a lot more expensive.
I would also not make the thread pool a singleton (it is tempting, admitted!) because a thread pool is a queue, so if it is a singleton, you may get undesirable effects. For example if you decide to run "search in files" in its own thread, then it will have to wait until the last syntax parsing job is finished - this does not make sense since these are not related tasks.
A singleton with a priority queue might be a consideration. You could queue "interactive" tasks to the queue with a higher priority. However, this is a lot more complicated (keep things simple!), and the management of the priority queue is probably more expensive than just spawning two or three more threads.
When advocating many threads, one important thing to keep in mind is memory. If you spawn off 50 threads with 1 MB of stack each, then you need 50 MB of memory only for these, so obviously the total number should not be a lot more than maybe 6-8.