I have a program in c++ with several threads in it. I want one of the threads to be able to read/get commands from the console while others continue running, for example: "play", "stop", "pause",...
something like:
while (1)
{
std::string str;
getline(std::cin, str);
/* do something */
}
Will it work? Any suggestions?
Thanks in advance.
Short Answer: Yes.
Long Answer: It depends of what you call 'work', there is nothing that prevent you from calling a blocking function/method from a thread while other threads are running.
However, threads share memory and resources. On an UNIX machine (and it's more or less the same on Windows), stdin and stdout are shared between threads. std::cin will manipulate stdin under the hood at some point, and you should ensure that only one thread can manipulate a given resource at a time.
You can do that by either make sure that only one thread can reach code using std::cin, or use synchronization, with a mutex/semaphore.
Related
I've got a function I need to call from a third-party library which I can't control. That function evaluates a command I pass in and prints its results to stdout. In my use case, I need to capture the results into a std::string variable (not write to a file), which I can do just fine in a single-threaded example:
int fd[2];
pid_t pid;
char *args[] = {};
if ( pid == 0 )
{
dup2( fd[1], STDOUT_FILENO );
close( fd[0] );
close( fd[1] );
char *args[] = {};
// This func will print the results I want to stdout, but I have no control over its code.
festival_eval_command("(print utt2)");
execv( args[0], args );
}
close( fd[1] );
char buffer[1000000];
ssize_t length = read( fd[0], buffer, sizeof(buffer) - 1 );
std::string RESULT = buffer;
memset(buffer, 0, sizeof buffer); // clear the buffer
// RESULT now holds the contents that would have been printed out in third_party_eval().
Some constraints/detail:
My program is multi-threaded, so other threads may be using stdout simultaneously (my understanding is that C++ ties the output from multiple threads into stdout)
The third-party library is Festival, an open-source speech synthesis library written in LISP (which I have no experience in). I'm using its C++ API by calling: festival_eval_command("(print utt2)");
festival_eval_command appears to use stdout, not std::cout (I've tested by redirecting both in a single-threaded program and only the stdout redirection captures the output from utt2)
As far as I can tell from the source, festival_eval_command doesn't allow for an alternate file descriptor.
This function is only being run in one of the threads of my multithreaded program, so I'm only concerned about isolating the festival_eval_command output from the other threads' stdout.
My question: Is there a way I can safely retrieve the just results of festival_eval_command() from stdout in a multi-threaded program? It sounds like my options are:
Launch this function in a separate process, which has its own stdout. Do the IO redirection in that separate process, get the output I need and return it back to my main program process. Is this correct? How would I go about doing this?
Use a mutex around the festival_eval_command. I don't quite understand how mutexes interact with other threads though. If I have this example:
void do_stuff_simultaneously() {
std::cout << "Printing output to terminal..." << std::endl;
}
// main thread
void do_stuff() {
// launch a separate thread that may print to stdout
std::thread t(do_stuff_simultaneously);
// lock stdout somehow
// redirect stdout to string variable
festival_eval_command("(print utt2)");
// unlock stdout
}
Does the locking of stdout prevent do_stuff_simultaneously from accessing it? Is there a way to make stdout thread-safe like this?
However, my program is multi-threaded, so other threads may be using stdout simultaneously
The outputs of threads are going to be interleaved in a fashion you cannot control. Unless each thread writes its entire output using one std::cout.write (see below for why).
Is there a way I can safely retrieve the just results of third_party_eval() from stdout in a multi-threaded program?
Each thread must run that function in a separate process, from which you capture its stdout into a std::string s (different one for each process).
Then in parent process you write that std::string into stdout with
std::cout.write(s.data(), s.size()). std::cout.write locks a mutex (to protect itself from data race and corruption when multiple threads write into it in any way, including operator<<), so that the output of one process is not interleaved with anything else.
Note up front: This shows why globals are often a bad idea! Even more, library code (i.e. code intended for re-use in different contexts) should never use globals. This is also something to tell the supplier of that code, they should fix their library to provide a version that at least takes an output filedescriptor instead of writing to stdout.
Here's what I would consider doing: Move the whole function execution to a separate process. That way, if multiple threads need to run it, they will start separate processes with separate outputs that they can process independently.
An alternative way is to wrap this single function. This wrapper does all the IO redirection and it (being a critical section) is guarded by a mutex, so that two threads invoking the wrapper will be serialized. However, this has downsides, because in the meantime, that code still messes with your process' standard streams (so a stray call to output something would be mixed into the function output).
A second alternative is to put the function into a wrapper process who's only goal is to serialize the use of the function. You'd start that process on demand or on start of your application and use some form of IPC to communicate with it.
I a have third party function which I use in my program. I can't replace it; it's in a dynamic library, so I also can't edit it. The problem is that it sometimes runs for too long.
So, can I do anything to stop this function from running if it runs more than 10 seconds for example? (It's OK to close program in this scenario.)
PS. I have Linux, and this program won't have to be ported anywhere else.
What I want is something like this:
#include <stdio.h>
#include <stdlib.h>
void func1 (void) // I can not change contents of this.
{
int i; // random
while (i % 2 == 0);
}
int main ()
{
setTryTime(10000);
timeTry{
func1();
} catchTime {
puts("function executed too long, aborting..");
}
return 0;
}
Sure. And you'd do it just the way you suggested in your title: "signals".
Specifically, an "alarm" signal:
http://linux.die.net/man/2/alarm
http://beej.us/guide/bgipc/output/html/multipage/signals.html
If you really have to do this, you probably want to spawn a process that does nothing but invoke the function and return its result to the caller. If it runs too long, you can kill that process.
By putting it into its own process, you stand a decent (not great, but decent) chance of cleaning up at least most of what it was doing so when it dies unexpectedly it probably won't make a complete mess of things that will lead to later problem.
The potential problem with forcefully cancelling a running function is that it may "own" resources that it intended to return later. The kind of resources that can be problems include:
heap memory allocations (free store)
shared memory segments
threads
sockets
file handles
locks
Some of these resources are managed on a per-process basis, so letting the function run in a different process (perhaps using fork) makes it easier to kill cleanly. Other resources can outlive a process, and really must be cleaned up explicitly. Depending on your operating system, it's also possible that the function may be part-way through interacting with some hardware driver or device, and killing it unexpectedly may leave that driver or device in a bizarre state such that it won't work until after a restart.
If you happen to know that the function doesn't use any of these kind of resources, then you can kill it confidently. But, it's hard to guarantee that: in a large system with many such decisions - which the compiler can't check - evolution of code in functions like func1() is likely to introduce dependencies on such resources.
If you must do this, I'd suggest running it in a different process or thread, and using kill() for processes, pthread_kill if func1() has some support for terminating when a flag is set asynchronously, or the non-portable pthread_cancel if there's really no other choice.
I have got a program which checks if there's a version update on the server. Now I have to do something like
if(update_avail) {
system("updater.exe");
exit(0);
}
but without waiting for "updater.exe" to complete. Otherwise I can't replace my main program because it is running. So how to execute "updater.exe" and immediately exit? I know the *nix way with fork and so on, how to do this in Windows?
Use CreateProcess(), it runs asynchronously. Then you would only have to ensure that updater.exe can write to the original EXE, which you can do by waiting or retrying until the original process has ended. (With a grace interval of course.)
There is no fork() in Win32. The API call you are looking for is called ::CreateProcess(). This is the underlying function that system() is using. ::CreateProcess() is inherently asynchronous: unless you are specifically waiting on the returned process handle, the call is non-blocking.
There is also a higher-level function ::ShellExecute(), that you could use if you are not redirecting process standard I/O or doing the waiting on the process. This has an advantage of searching the system PATH for the executable file, as well as the ability to launch batch files and even starting a program associated with a document file.
You need a thread for that
Look here: http://msdn.microsoft.com/en-us/library/y6h8hye8(v=vs.80).aspx
You are currently writing your code in the "main thread" (which usually is also your frame code).
So if you run something that takes time to complete it will halt the execution of your main thread, if you run it in a second thread your main thread will continue.
Update:
I've missed the part that you want to exit immediately.
execl() is likely what you want.
#include <unistd.h>
int main(){
execl("C:\\path\\to\\updater.exe", (const char *) 0);
return 0;
}
The suggested CreateProcess() can be used as well but execl is conforming to POSIX and would keep your code more portable (if you care at all).
#include <unistd.h>
extern char **environ;
int execl(const char *path, const char *arg, ...);
Update:
tested on Win-7 using gcc as compiler
I'm writing a server(mainly for windows, but it would be cool if i could keep it multiplatform) and i just use a normal console window for it. However, I want the server to be able to do commands like say text_to_say_here or kick playername, etc. How can i have a asynchronous input/output? I allready tried some stuff with the normal printf() and gets_s but that resulted in some really.... weird stuff.
I mean something like this 1
thanks.
Quick code to take advantage of C++11 features (i.e. cross-platform)
#include <atomic>
#include <thread>
#include <iostream>
void ReadCin(std::atomic<bool>& run)
{
std::string buffer;
while (run.load())
{
std::cin >> buffer;
if (buffer == "Quit")
{
run.store(false);
}
}
}
int main()
{
std::atomic<bool> run(true);
std::thread cinThread(ReadCin, std::ref(run));
while (run.load())
{
// main loop
}
run.store(false);
cinThread.join();
return 0;
}
You can simulate asynchronous I/O using threads, but more importantly, you must share a mutex between the two read/write threads in order to avoid any issues with a thread stepping on another thread, and writing to the console on top of the output of another thread. In other words std::cout, std::cin, fprintf(), etc. are not multi-thread safe, and as a result, you will get an unpredictable interleaving pattern between the two operations where a read or write takes place while another read or write was already happening. You could easily end up with a read trying to take place in the middle of a write, and furthermore, while you're typing an input on the console, another writing thread could start writing on the console, making a visual mess of what you're trying to type as input.
In order to properly manage your asynchronous read and write threads, it would be best to setup two classes, one for reading, and another for writing. In each class, setup a message queue that will either store messages (most likely std::string) for the main thread to retrieve in the case of the read thread, and for the main thread to push messages to in the case of the write thread. You may also want to make a special version of your read thread that can print a prompt, with a message pushed into its message queue by the main thread that will print a prompt before reading from stdin or std::cin. Both classes will then share a common mutex or semaphore to prevent unpredictable interleaving of I/O. By locking the common mutex before any iostream calls (an unlocking it afterwards), any unpredictable interleaving of I/O will be avoided. Each thread will also add another mutex that is unique to each thread that can be used to maintain exclusivity over access to the class's internal message queue. Finally, you can implement the message queues in each class as a std::queue<std::string>.
If you want to make your program as cross-platform as possible, I would suggest implementing this with either Boost::threads, or using the new C++0x std::threads libraries.
If you ditch the console window and use TCP connections for command and control, your server will be much easier to keep multi-platform, and also simpler and more flexible.
You can try placing the input and output on separate threads. I'm not quite sure why you want to do this, but threading should do the job.
:)
http://en.wikibooks.org/wiki/C++_Programming/Threading
I've recently managed to create a thread using the boost::bind function.
For the time being, I'm having the thread display to stdout. I can see the output if I use thread.join. However, if I don't do this, I don't see any output.
Why is this?
I'm hoping I don't have to use the join function, because I would like to call this function multiple times, without having to wait for the previously launched thread to finish.
Thanks for your responses. What I really wanted to make sure of was that the thread actually executed. So I added a system call to touch a non-existent file, and it was there afterwards, so the thread did execute.
I can see the output if I use thread.join. However, if I don't do this, I don't see any output. Why is this?
Most probably this is a side-effect of the way standard output is buffered on your system. Do you have '\n' and/or endl sprinkled around in every print statement? That should force output (endl will flush the stream in addition).
If you look at the documentation for join, you'd see that this function is called to wait till until termination of the thread. When a thread is terminated (or for that matter, a process) all buffered output is flushed.
You do not need to wait till the thread has completed execution in order to see output. There are at least a couple of ways (I can remember off the top of my head) you can achieve this:
Make cout/stdout unbuffered, or
Use \n and fflush(stdout) (for C-style I/O) or std::endl stream manipulator
By default the thread object's destructor does not join to the main thread, could it be that your main thread terminates and closes STDOUT before the thread manages to flush its output?
Note that in C++0x the default destructor for thread does join (rather than detach as in boost) so this will not happen (see A plea to reconsider detach-on-destruction for thread objects).
Note: Since this was written the C++11 standard was changed and an unjoined thread now terminates the process.