On OSX, I use the following to get input asynchronously with a time-out..
#include <chrono>
#include <mutex>
#include <string>
#include <iostream>
#if defined(_WIN32) || defined(_WIN64)
#include <windows.h>
#else
#include <pthread.h>
#endif
#if defined(_WIN32) || defined(_WIN64)
#define THREAD_RETURN_TYPE DWORD
#else
#define THREAD_RETURN_TYPE void*
#endif
class semaphore
{
private:
std::mutex mutex;
std::condition_variable condition;
uint32_t count = 0;
public:
void signal()
{
std::unique_lock<std::mutex> lock(mutex);
++count;
condition.notify_one();
}
void wait()
{
std::unique_lock<std::mutex> lock(mutex);
condition.wait(lock, [&] {
return count > 0;
});
--count;
}
bool try_wait()
{
std::unique_lock<std::mutex> lock(mutex);
if (count > 0)
{
--count;
return true;
}
return false;
}
template<typename Rep, typename Period>
bool wait_for(const std::chrono::duration<Rep, Period>& relative_time)
{
std::unique_lock<std::mutex> lock(mutex);
bool finished = condition.wait_for(lock, relative_time, [&] {
return count > 0;
});
if (finished)
{
--count;
}
return finished;
}
template<typename Duration>
bool wait_until(const std::chrono::time_point<std::chrono::high_resolution_clock, Duration>& absolute_time)
{
std::unique_lock<std::mutex> lock(mutex);
bool finished = condition.wait_until(lock, absolute_time, [&] {
return count > 0;
});
if (finished)
{
--count;
}
return finished;
}
template<typename Clock, typename Duration>
bool wait_until(const std::chrono::time_point<Clock, Duration>& absolute_time)
{
return wait_until(std::chrono::high_resolution_clock::now() + (absolute_time - Clock::now()));
}
};
class simple_thread
{
private:
#if defined(_WIN32) || defined(_WIN64)
HANDLE thread;
#else
pthread_t thread;
#endif
public:
simple_thread(THREAD_RETURN_TYPE (*threadFunc)(void*), void* args)
{
#if defined(_WIN32) || defined(_WIN64)
thread = CreateThread(0, 0, static_cast<LPTHREAD_START_ROUTINE>(threadFunc), args, 0, 0);
#else
pthread_create(&thread, nullptr, threadFunc, args);
#endif
}
void join()
{
#if defined(_WIN32) || defined(_WIN64)
WaitForSingleObject(thread, INFINITE);
#else
pthread_join(thread, nullptr);
#endif
}
void detach()
{
#if defined(_WIN32) || defined(_WIN64)
CloseHandle(thread);
#else
pthread_detach(thread);
#endif
}
void abort()
{
#if defined(_WIN32) || defined(_WIN64)
TerminateThread(thread, 0);
#else
pthread_cancel(thread);
#endif
}
};
THREAD_RETURN_TYPE getInput(void* args)
{
std::string* input = static_cast<std::string*>(static_cast<void**>(args)[0]);
semaphore* sem = static_cast<semaphore*>(static_cast<void**>(args)[1]);
getline(std::cin, *input);
sem->signal();
return 0;
}
int main()
{
std::string input;
semaphore sem;
void* args[2] = {&input, &sem};
simple_thread thread(getInput, args);
if (sem.wait_for(std::chrono::seconds(5)))
{
std::cout<<"Input";
thread.join();
}
else
{
std::cout<<"Invalid Input";
thread.abort();
}
}
You can use pthread to create a semaphore with mutex as well.. or use c++11 like above..
One other thing is that I created my own threading class because I couldn't find a way to kill an std::thread
..