I'm working on my radio transmitter and have just ported it to Linux. Here is the problem:
void input_thread()
{
char buffer[128];
cout << "Waiting for input\n";
for (;;)
{
cout << "say> ";
if (cin.getline(buffer, 127).fail())
// Ctrl+C
break;
else if (strlen(buffer) == 0)
continue;
signal_source.feed(buffer);
}
}
I use a std::thread and hope it break the loop when gets a Ctrl+C. This piece of code works well on Windows but not on Linux. I'm wondering if there is a way to safely break the loop so that I can join the thread without causing deadlock? Thanks.
Related
Consider the following two snippets of code where I am trying to launch 10000 threads:
Snippet 1
std::array<std::future<void>, 10000> furArr_;
try
{
size_t index = 0;
for (auto & fut : furArr_)
{
std::cout << "Created thread # " << index++ << std::endl;
fut = std::async(std::launch::async, fun);
}
}
catch (std::system_error & ex)
{
std::string str = ex.what();
std::cout << "Caught : " << str.c_str() << std::endl;
}
// I will call get afterwards, still 10000 threads should be active by now assuming "fun" is time consuming
Snippet 2
std::array<std::thread, 10000> threadArr;
try
{
size_t index = 0;
for (auto & thr : threadArr)
{
std::cout << "Created thread # " << index++ << std::endl;
thr = std::thread(fun);
}
}
catch (std::system_error & ex)
{
std::string str = ex.what();
std::cout << "Caught : " << str.c_str() << std::endl;
}
The first case always succeeds .i.e. I am able to create 10000 threads and then I have to wait for all of them to finish. In the second case, almost always I end up getting an exception("resource unavailable try again") after creating 1600+ threads.
With a launch policy of std::launch::async, I thought that the two snippets should behave the same way. How different std::async with a launch policy of async is from launching a thread explicitly using std::thread?
I am on Windows 10, VS2015, binary is built in x86 release mode.
Firstly, thanks to Igor Tandetnik for giving me the direction for this answer.
When we use std::async (with async launch policy), we are saying:
“I want to get this work done on a separate thread”.
When we use std::thread we are saying:
“I want to get this work done on a new thread”.
The subtle difference means that async (is usually) implemented using thread pools. Which means if we have invoked a method using async multiple times, often the thread id inside that method will repeat i.e. async allocates multiple jobs to the same set of threads from the pool. Whereas with std::thread, it never will.
This difference means that launching threads explicitly will be potentially more resource intensive (and thus the exception) than using async with async launch policy.
I am in the middle of developing a game and came across the problem of multithreading. I already used multithreading successfully when loading resources. I did that by creating some threads at some point, assigned them functions, and waited for them to finish, while drawing a loading screen, pretty straightforward.
Now I want to create some threads, that can wait idle till they receive a function, when they do, solve that, then stay idle again. They must operate in a game loop, which is roughly like this (I came up with these function names just for easy visualization):
std::thread t0,t1;
while(gamerunning)
{
UpdateGame();
t0.receiveFunc( RenderShadow );
t1.receiveFunc( RenderScene );
WaitForThreadstoFinishWork();
RenderEverything(); //Only draw everything if the threads finished (D3D11's Deferred Context rendering)
}
t0.Destroy();
t1.Destroy();
My rendering engine is working, and for the time being (for testing), I created threads in my game loop, which is a terrible way of even a quick test, because my rendering speed even slowed down. By the way, I am using C++11's library.
Long story short, I want to create threads before my game loop takes place, and use those in the game loop afterwards, hope someone can help me out. If it is an option, I would really want to stay away from the lower levels of threading, I just need the most straightforward way of doing this.
Following your most recent comments, here is an example implementation of a thread that wakes up on demand, runs its corresponding task and then goes back to sleep, along with the necessary functions to manage it (wait for task completion, ask for shutdown, wait for shutdown).
Since your set of functions is fixed, all you'll have left to do is to create as much threads as you need (ie. 7, probably in a vector), each with its own corresponding task.
Note that once you remove the debugging couts there's little code left, so I don't think there is a need to explain the code (it's pretty self-explanatory IMHO). However don't hesitate to ask if you need explanations on some details.
class TaskThread {
public:
TaskThread(std::function<void ()> task)
: m_task(std::move(task)),
m_wakeup(false),
m_stop(false),
m_thread(&TaskThread::taskFunc, this)
{}
~TaskThread() { stop(); join(); }
// wake up the thread and execute the task
void wakeup() {
auto lock = std::unique_lock<std::mutex>(m_wakemutex);
std::cout << "main: sending wakeup signal..." << std::endl;
m_wakeup = true;
m_wakecond.notify_one();
}
// wait for the task to complete
void wait() {
auto lock = std::unique_lock<std::mutex>(m_waitmutex);
std::cout << "main: waiting for task completion..." << std::endl;
while (m_wakeup)
m_waitcond.wait(lock);
std::cout << "main: task completed!" << std::endl;
}
// ask the thread to stop
void stop() {
auto lock = std::unique_lock<std::mutex>(m_wakemutex);
std::cout << "main: sending stop signal..." << std::endl;
m_stop = true;
m_wakecond.notify_one();
}
// wait for the thread to actually be stopped
void join() {
std::cout << "main: waiting for join..." << std::endl;
m_thread.join();
std::cout << "main: joined!" << std::endl;
}
private:
std::function<void ()> m_task;
// wake up the thread
std::atomic<bool> m_wakeup;
bool m_stop;
std::mutex m_wakemutex;
std::condition_variable m_wakecond;
// wait for the thread to finish its task
std::mutex m_waitmutex;
std::condition_variable m_waitcond;
std::thread m_thread;
void taskFunc() {
while (true) {
{
auto lock = std::unique_lock<std::mutex>(m_wakemutex);
std::cout << "thread: waiting for wakeup or stop signal..." << std::endl;
while (!m_wakeup && !m_stop)
m_wakecond.wait(lock);
if (m_stop) {
std::cout << "thread: got stop signal!" << std::endl;
return;
}
std::cout << "thread: got wakeup signal!" << std::endl;
}
std::cout << "thread: running the task..." << std::endl;
// you should probably do something cleaner than catch (...)
// just ensure that no exception propagates from m_task() to taskFunc()
try { m_task(); } catch (...) {}
std::cout << "thread: task completed!" << std::endl;
std::cout << "thread: sending task completed signal..." << std::endl;
// m_wakeup is atomic so there is no concurrency issue with wait()
m_wakeup = false;
m_waitcond.notify_all();
}
}
};
int main()
{
// example thread, you should really make a pool (eg. vector<TaskThread>)
TaskThread thread([]() { std::cout << "task: running!" << std::endl; });
for (int i = 0; i < 2; ++i) { // dummy example loop
thread.wakeup();
// wake up other threads in your thread pool
thread.wait();
// wait for other threads in your thread pool
}
}
Here's what I get (actual order varies from run to run depending on thread scheduling):
main: sending wakeup signal...
main: waiting for task completion...
thread: waiting for wakeup or stop signal...
thread: got wakeup signal!
thread: running the task...
task: running!
thread: task completed!
thread: sending task completed signal...
thread: waiting for wakeup or stop signal...
main: task completed!
main: sending wakeup signal...
main: waiting for task completion...
thread: got wakeup signal!
thread: running the task...
task: running!
thread: task completed!
thread: sending task completed signal...
thread: waiting for wakeup or stop signal...
main: task completed!
main: sending stop signal...
main: waiting for join...
thread: got stop signal!
main: joined!
After several days of searching it's time to ask. Environment is Ubuntu 12.04/Gnome.
I'm developing some embedded code on the ubuntu box and testing as much as I can in that environment before porting over to the embedded processor. The current routine is a real time fast fourier transform and I want to use gnuplot to display the results. So I want my test code AND gnuplot to run in the foreground at the same time and communicate via a pipe.
I did the usual popen() call and that worked except for one thing. stdin for the child (gnuplot) is still attached to the console. It is in contention with the parent process. The parent process needs to receive keystrokes to modify its behaviour. Sometimes the parent gets the keystroke and sometimes gnuplot does.
So I've tried the fork/exec path. Specifically
pid_t pg = tcgetpgrp(1); // get process group associated with stdout
cerr << "pid_t pg = " << pg << endl;
cerr << "process pid is " << getpid() << endl;
if (pipe(pipefd) == -1) {// open the pipe
cerr << "pipe failure" << endl;
exit(3);
} // if pipe
cpid = fork();
if (cpid == -1) {
cerr << "fork failure" << endl;
exit(1);
}
if (cpid == 0) { // this is the child process
if (tcsetpgrp(1, pg) == -1) { // this should set the process associated with stdin (gnuplot) with the
cerr << "tcsetgrp failed" << endl; // foreground terminal.
exit(7);
}
close(pipefd[1]); // close child's writing handle
if (pipefd[0] != STDIN_FILENO) { // this changes the file descripter of stdin back to 0
if ( dup2(pipefd[0], STDIN_FILENO) != STDIN_FILENO) {
cerr << "dup2 error on stdin" << endl;
exit(6);
}
}
if (execl("/usr/bin/gnuplot", "gnuplot", "-background", "white", "-raise", (char *) NULL)) {
cerr << "execl failed" << endl;
exit(2);
} else // if exec
close(pipefd[0]); // close parent's reading handle
} // if cpid
// back in parent process
This fires off gnuplot as I expect it should. I can see gnuplot consuming all the resources of one core as it normally does. The problem is that no graph appears on the screen.
So my question is, how do I start a child process, totally detach it from the console so it won't get any keystrokes and get the output of gnuplot to display?
i have a watchdog stop function placed inside the deconstructor of the process that i executed from my C++ program. Everytime i close using the "X" button on that process QT GUI, it will run thru the codes that i placed in the deconstructor. but when i try to do a Qprocesskill/close/terminate to kill the process in my C++ program, the codes in the deconstructors(of the process) are not being executed. Anyone knows whats wrong or have alternative methods to close the process? Thanks!!!
Btw im on linux.
No objects get torn down when the process abruptly exits with those functions. They're the equivalent to the C function exit(1). Try gracefully exiting the event loop of your QApplication::exec by calling QApplication::quit () which will exit the main event loop inside of exec and allow main to exit normally and allowing all objects that would normally destroy themselves at that point to do so.
Use std::signal to register the handlers for those signals (http://en.cppreference.com/w/cpp/utility/program/signal):
#include <csignal>
#include <iostream>
namespace
{
volatile std::sig_atomic_t gSignalStatus;
}
void signal_handler(int signal)
{
gSignalStatus = signal;
}
int main()
{
// Install a signal handler
std::signal(SIGINT, signal_handler);
std::cout << "SignalValue: " << gSignalStatus << '\n';
std::cout << "Sending signal " << SIGINT << '\n';
std::raise(SIGINT);
std::cout << "SignalValue: " << gSignalStatus << '\n';
}
I have a hard problem here, which I can not solve and do not find the right answer on the net:
I have created a detached thread with a clean up routing, the problem is that on my Imac and Ubuntu 9.1 (Dual Core). I am not able to correctly cancel the detached thread in the fallowing code:
#include <iostream>
#include <pthread.h>
#include <sched.h>
#include <signal.h>
#include <time.h>
pthread_mutex_t mutex_t;
using namespace std;
static void cleanup(void *arg){
pthread_mutex_lock(&mutex_t);
cout << " doing clean up"<<endl;
pthread_mutex_unlock(&mutex_t);
}
static void *thread(void *aArgument)
{
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,NULL);
pthread_cleanup_push(&cleanup,NULL);
int n=0;
while(1){
pthread_testcancel();
sched_yield();
n++;
pthread_mutex_lock(&mutex_t);
cout << " Thread 2: "<< n<<endl; // IF I remove this endl; --> IT WORKS!!??
pthread_mutex_unlock(&mutex_t);
}
pthread_cleanup_pop(0);
return NULL;
}
int main()
{
pthread_t thread_id;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
int error;
if (pthread_mutex_init(&mutex_t,NULL) != 0) return 1;
if (pthread_create(&thread_id, &attr, &(thread) , NULL) != 0) return 1;
pthread_mutex_lock(&mutex_t);
cout << "waiting 1s for thread...\n" <<endl;
pthread_mutex_unlock(&mutex_t);
int n =0;
while(n<1E3){
pthread_testcancel();
sched_yield();
n++;
pthread_mutex_lock(&mutex_t);
cout << " Thread 1: "<< n<<endl;
pthread_mutex_unlock(&mutex_t);
}
pthread_mutex_lock(&mutex_t);
cout << "canceling thread...\n" <<endl;
pthread_mutex_unlock(&mutex_t);
if (pthread_cancel(thread_id) == 0)
{
//This doesn't wait for the thread to exit
pthread_mutex_lock(&mutex_t);
cout << "detaching thread...\n"<<endl;
pthread_mutex_unlock(&mutex_t);
pthread_detach(thread_id);
while (pthread_kill(thread_id,0)==0)
{
sched_yield();
}
pthread_mutex_lock(&mutex_t);
cout << "thread is canceled";
pthread_mutex_unlock(&mutex_t);
}
pthread_mutex_lock(&mutex_t);
cout << "exit"<<endl;
pthread_mutex_unlock(&mutex_t);
return 0;
}
When I replace the Cout with printf() i workes to the end "exit" , but with the cout (even locked) the executable hangs after outputting "detaching thread...
It would be very cool to know from a Pro, what the problem here is?.
Why does this not work even when cout is locked by a mutex!?
THE PROBELM lies in that COUT has a implicit cancelation point!
We need to code like this:
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
pthread_testcancel();
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL);
and make the thread at the beginning :
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL);
That ensures that only pthread_cancel() has a cancelation point...
Try commenting out the line pthread_detach(thread_id); and run it. You are creating the thread as detached with your pthread_attr_t.
Either that, or try passing NULL instead of &attr in the pthread_create (so that the thread is not created detached) and run it.
I would guess that if the timing is right, the (already detached) thread is gone by the time the main thread attempts the pthread_detach, and you are going off into Never Never Land in pthread_detach.
Edit:
If cout has an implicit cancelation point as Gabriel points out, then most likely what happens is that the thread cancels while holding the mutex (it never makes it to pthreads_unlock_mutex after the cout), and so anybody else waiting on the mutex will be blocked forever.
If the only resource you need to worry about is the mutex, you could keep track of whether or not your thread has it locked and then unlock it in the cleanup, assuming that cleanup runs in the same thread.
Take a look here, page 157 on: PThreads Primer.