I am trying to modify the following code to use sigaction() to intercept SIGINT;
I need to replace the "for" loop with "while ( 1 ); you should be able to quit the program by entering "^\". (Need to intercept SIGQUIT.)
#include <signal.h>
#include <unistd.h>
#include <iostream>
using namespace std;
void func ( int sig )
{
cout << "Oops! -- I got a signal " << sig << endl;
}
int main()
{
(void) signal ( SIGINT, func ); //catch terminal interrupts
//for ( int i = 0; i < 20; ++i )
while(1)
{
cout << "signals" << endl;
sleep ( 1 );
}
return 0;
}
You can use sigaction to catch SIGINT (and still have the output you've described) with the following code (which compiles and works for me using clang on a Unix like OS):
#include <signal.h>
#include <iostream>
#include <unistd.h>
static int sigcaught = 0;
static void sighandler(int signum)
{
sigcaught = signum;
}
int main()
{
int signum = SIGINT;
struct sigaction newact;
struct sigaction oldact;
newact.sa_handler = sighandler;
sigemptyset(&newact.sa_mask);
newact.sa_flags = 0;
sigaction(signum, &newact, &oldact);
while (!sigcaught)
{
std::cout << "waiting for signal" << std::endl;
sleep(1);
}
std::cout << "Oops! -- I got a signal " << sigcaught << std::endl;
return 0;
}
Please note that: this code intentionally isn't checking return values (like from sigaction nor sleep) since the original code isn't and since checking them may detract a reader from seeing the relevant differences. I would not want production code to ignore return values however (particularly those that can indicate errors).
Related
I need your help. Program A executes program B with fork(). Every 5 seconds the process belonging to program B is interrupted. If the user enters any key within a certain time, the process is continued and interrupted again after the same time interval. If no key is entered, both program A and program B are terminated prematurely. I have tried the following code, but it does not work. Any suggestions/tips that will help me?
#include <iostream>
#include <chrono>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
using namespace std;
using namespace chrono;
int pid;
void signal_handler(int signum) {
cout << "Programm B is interrupted. Please enter any key within 5 or the programm will be terminated" << endl;
kill(pid,SIGSTOP);
alarm(5);
pause();
alarm(5);
}
int main(int argc, char* argv[]) {
//Usage
if(string(argv[1]) == "h" || string(argv[1]) == "help"){
cout << "usage" << endl;
return 0;
}
signal(SIGALRM, signal_handler);
pid = fork();
if (pid == 0) {
cout << "Name of programm B: " << argv[1] << endl;
cout << "PID of programm B: " << getpid() << endl;
execvp(argv[1], &argv[1]);
} else if (pid > 0) {
cout << "PID of programm A: " << getpid() << endl;
high_resolution_clock::time_point t1 = high_resolution_clock::now();
waitpid(pid, nullptr, 0);
high_resolution_clock::time_point t2 = high_resolution_clock::now();
auto duration = duration_cast<milliseconds>(t2 - t1).count();
cout << "Computing time: " << duration << "ms" << endl;
} else {
cerr << "error << endl;
return 1;
}
return 0;
}
Any help or sulution. I am a beginner in c++ btw.
Signals can get tricky and there are lots of issues with your approach.
You should:
kick off the timer (alarm(5)) in main
do the sighandler registration and timer kick-off after you've spawned the child (or you somewhat risk running the signal handler in the child in between fork and execvp)
use sigaction rather than signal to register the signal, as the former has clear portable semantics unlike the latter
loop on EINTR around waitpid (as signal interruptions will cause waitpid to fail with EINTR)
As for the handler, it'll need to
use only async-signal-safe functions
register another alarm() around read
unblock SIGALRM for the alarm around read but not before you somehow mark yourself as being in your SIGALRM signal handler already so the potential recursive entry of the handler can do a different thing (kill the child and exit)
(For the last point, you could do without signal-unblocking if you register the handler with .sa_flags = SA_NODEFER, but that has the downside of opening up your application to stack-overflow caused by many externally sent (via kill) SIGALRMs. If you wanted to handle externally sent SIGALRMs precisely, you could register the handler with .sa_flags=SA_SIGINFO and use info->si_code to differentiate between user-sends and alarm-sends of SIGALRM, presumably aborting on externally-sent ones)
It could look something like this (based on your code):
#include <iostream>
#include <chrono>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <string.h>
//AS-safe raw io helper functions
ssize_t /* Write "n" bytes to a descriptor */
writen(int fd, const char *ptr, size_t n)
{
size_t nleft;
ssize_t nwritten;
nleft = n;
while (nleft > 0) {
if ((nwritten = write(fd, ptr, nleft)) < 0) {
if (nleft == n)
return(-1); /* error, return -1 */
else
break; /* error, return amount written so far */
} else if (nwritten == 0) {
break;
}
nleft -= nwritten;
ptr += nwritten;
}
return(n - nleft); /* return >= 0 */
}
ssize_t writes(int fd, char const *str0) { return writen(fd,str0,strlen(str0)); }
ssize_t writes2(char const *str0) { return writes(2,str0); }
//AS-safe sigprockmask helpers (they're in libc too, but not specified as AS-safe)
int sigrelse(int sig){
sigset_t set; sigemptyset(&set); sigaddset(&set,sig);
return sigprocmask(SIG_UNBLOCK,&set,0);
}
int sighold(int sig){
sigset_t set; sigemptyset(&set); sigaddset(&set,sig);
return sigprocmask(SIG_BLOCK,&set,0);
}
#define INTERRUPT_TIME 5
using namespace std;
using namespace chrono;
int pid;
volatile sig_atomic_t recursing_handler_eh; //to differentiate recursive executions of signal_handler
void signal_handler(int signum) {
char ch;
if(!recursing_handler_eh){
kill(pid,SIGSTOP);
writes2("Programm B is interrupted. Please type enter within 5 seconds or the programm will be terminated\n");
alarm(5);
recursing_handler_eh = 1;
sigrelse(SIGALRM);
if (1!=read(0,&ch,1)) signal_handler(signum);
alarm(0);
sighold(SIGALRM);
writes2("Continuing");
kill(pid,SIGCONT);
recursing_handler_eh=0;
alarm(INTERRUPT_TIME);
return;
}
kill(pid,SIGTERM);
_exit(1);
}
int main(int argc, char* argv[]) {
//Usage
if(string(argv[1]) == "h" || string(argv[1]) == "help"){
cout << "usage" << endl;
return 0;
}
pid = fork();
if (pid == 0) {
cout << "Name of programm B: " << argv[1] << endl;
cout << "PID of programm B: " << getpid() << endl;
execvp(argv[1], &argv[1]);
} else if (pid < 0) { cerr << "error" <<endl; return 1; }
struct sigaction sa; sa.sa_handler = signal_handler; sigemptyset(&sa.sa_mask); sa.sa_flags=0; sigaction(SIGALRM, &sa,0);
//signal(SIGALRM, signal_handler);
alarm(INTERRUPT_TIME);
cout << "PID of programm A: " << getpid() << endl;
high_resolution_clock::time_point t1 = high_resolution_clock::now();
int r;
do r = waitpid(pid, nullptr, 0); while(r==-1 && errno==EINTR);
high_resolution_clock::time_point t2 = high_resolution_clock::now();
auto duration = duration_cast<milliseconds>(t2 - t1).count();
cout << "Computing time: " << duration << "ms" << endl;
return 0;
}
Not that the above will wait only for an enter key. To wait for any key, you'll need to put your terminal in raw/cbreak mode and restore the previous settings on exit (ideally on signal deaths too).
I'm playing with signal handling in UNIX and C++ and came across with this issue. I'm trying to write a program that counts to 10, one number per second, and when the user tries to interrupt it with a SIGINT (like CTRL+C) it prints a message telling it it will continue to count no matter what.
So far, I got this:
#include <iostream>
#include <signal.h>
#include <zconf.h>
using namespace std;
sig_atomic_t they_want_to_interrupt = 0;
void sigint_handler(int signum) {
assert(signum == SIGINT);
they_want_to_interrupt = 1;
}
void register_handler() {
struct sigaction sa;
sigemptyset(&sa.sa_mask);
sigaddset(&sa.sa_mask, SIGINT);
sa.sa_handler = sigint_handler;
sigaction(SIGINT, &sa, 0);
}
int main() {
register_handler();
cout << "Hi! We'll count to a hundred no matter what" << endl;
for (int i = 1; i <= 100; i++) {
if (they_want_to_interrupt == 1) {
cout << endl << "DON'T INTERRUPT ME WHILE I'M COUNTING! I'll count ALL THE WAY THROUGH!!!" << endl;
they_want_to_interrupt = 0;
}
cout << i << " " << flush;
sleep(1);
}
cout << "Done!" << endl;
return 0;
}
Now, the first time around I send the interrupt signal it works properly:
Hi! We'll count to a hundred no matter what
1 2 ^C
DON'T INTERRUPT ME WHILE I'M COUNTING! I'll count ALL THE WAY THROUGH!!!
3 4
But if I send a second interrupt signal, the process is stopped.
Why does it happen? I tried reading the manual on ´sigaction´ to try to see if there's something that will make the handler I created not be popped when the signal is caught and roll back to SIG_DFL, but couldn't work it out.
Thanks
You can just reset the signal handler each time a signal is sent. I've seen this for handling SIGUSR when a signal might be expected repeatedly.
#include <iostream>
#include <cassert>
#include <signal.h>
#include <zconf.h>
using namespace std;
void register_handler();
sig_atomic_t they_want_to_interrupt = 0;
void sigint_handler(int signum) {
assert(signum == SIGINT);
they_want_to_interrupt = 1;
register_handler();
}
void register_handler() {
struct sigaction sa;
sigemptyset(&sa.sa_mask);
sigaddset(&sa.sa_mask, SIGINT);
sa.sa_handler = sigint_handler;
sigaction(SIGINT, &sa, 0);
}
int main() {
register_handler();
cout << "Hi! We'll count to a hundred no matter what" << endl;
for (int i = 1; i <= 100; i++) {
if (they_want_to_interrupt == 1) {
cout << endl << "DON'T INTERRUPT ME WHILE I'M COUNTING! I'll count ALL THE WAY THROUGH!!!" << endl;
they_want_to_interrupt = 0;
}
cout << i << " " << flush;
sleep(1);
}
cout << "Done!" << endl;
return 0;
}
In this code:
struct sigaction sa;
sigemptyset(&sa.sa_mask);
sigaddset(&sa.sa_mask, SIGINT);
sa.sa_handler = sigint_handler;
sigaction(SIGINT, &sa, 0);
the sa.sa_flags field (and others) are uninitialized which may cause unexpected results. It would be better to zero-initialize the struct at the start, e.g.:
struct sigaction sa = { 0 };
Also, the sig_atomic_t flag should be declared as volatile to prevent the optimizer introducing unexpected behaviour.
I am following Boost multithreading tutorial here
. Following section 18.13, I try creating a class containing multiple threads as follows:
#define _CRT_SECURE_NO_WARNINGS
#include <ctime>
#include <iostream>
#include <string>
#include <queue>
#include <boost/array.hpp>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/asio.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/thread.hpp>
#include <boost/thread/thread.hpp>
#include <boost/chrono.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
using boost::asio::ip::udp;
using std::cout;
using std::cin;
using std::endl;
using std::string;
using namespace std;
class MultiTask
{
private:
boost::thread_group threads; // thread group
boost::thread* thread_main; // main thread
boost::thread* thread_output; // output thread
boost::thread* thread_input; // input thread
boost::mutex stopMutex;
bool stop;
int i_in, i_out, i_main;
string userInput;
public:
// constructor
MultiTask()
{
thread_main = new boost::thread(boost::ref(*this));
thread_output = new boost::thread(&MultiTask::Callable_Out, this, 1000, boost::ref(i_out));
thread_input = new boost::thread(&MultiTask::Callable_In, this, 1000, boost::ref(i_out), boost::ref(userInput));
//threads.add_thread(thread_main); // main thread = 0 // will throw -> boost thread: trying to join itself
threads.add_thread(thread_output); // output thread = 1
threads.add_thread(thread_input); // input thread = 2
stop = false;
i_in = 0;
i_out = 0;
i_main = 0;
userInput = "";
}
// destructor
~MultiTask()
{
// stop all threads
Stop();
// show exit message
cout << "Exiting MultiTask." << endl;
}
// start the threads
void Start()
{
// Wait till they are finished
threads.join_all();
}
// stop the threads
void Stop()
{
// warning message
cout << "Stopping all threads." << endl;
// signal the threads to stop (thread-safe)
stopMutex.lock();
stop = true;
stopMutex.unlock();
// wait for the threads to finish
threads.interrupt_all();
threads.join_all();
}
void Callable_Out(int interval, int& count)
{
while (1)
{
//cout << "Callable_Out [" << count++ << "]" << endl;
boost::this_thread::sleep(boost::posix_time::millisec(interval));
boost::this_thread::interruption_point();
}
}
void Callable_In(int interval, int& count, string& userInput)
{
while (1)
{
cout << "Callable_In [" << count++ << "]. Enter message: ";
getline(cin, userInput);
boost::this_thread::sleep(boost::posix_time::millisec(interval));
boost::this_thread::interruption_point();
}
}
// Thread function
void operator () ()
{
while (1)
{
//cout << "Main [" << i_main++ << "]." << endl;
//cout << "Main [" << i_main++ << "]. " << userInput << endl;
if (userInput == "STOP")
{
try
{
this->Stop();
}
catch(exception e)
{
cout << e.what() << endl;
}
}
boost::this_thread::sleep(boost::posix_time::millisec(1000));
boost::this_thread::interruption_point();
}
}
};
int main()
{
MultiTask mt;
mt.Start();
}
However, VS throws two of these errors:
Severity Code Description Project File Line Suppression State
Error C2198 'void (__cdecl *)(boost::posix_time::millisec,int &,std::string &)': too few arguments for call mycpp c:\boost_1_66_0\boost\bind\bind.hpp 259
Can someone please help? This is from section 18.13. Also, I do not see where to input the arguments for CallableFunction() in that example. How can it be done in my case? Thanks.
In tutorial CallableFunction function takes only one parameter, it is passed as second parameter in thread constructor new boost::thread(&CallableFunction, i);.
In your case Callable_Out takes 2 parameters, one is missing, you should call
thread_output = new boost::thread(&Callable_Out, boost::posix_time::millisec(0), boost::ref(i_out));
and for Callable_In you call
thread_input = new boost::thread(&Callable_In, boost::posix_time::millisec(1), boost::ref(i_out), boost::ref(userInput));
I'm looking for a (multiplatform) way to do non-blocking console input for my C++ program, so I can handle user commands while the program continually runs. The program will also be outputting information at the same time.
What's the best/easiest way to do this? I have no problem using external libraries like boost, as long as they use a permissive license.
Example using C++11:
#include <iostream>
#include <future>
#include <thread>
#include <chrono>
static std::string getAnswer()
{
std::string answer;
std::cin >> answer;
return answer;
}
int main()
{
std::chrono::seconds timeout(5);
std::cout << "Do you even lift?" << std::endl << std::flush;
std::string answer = "maybe"; //default to maybe
std::future<std::string> future = std::async(getAnswer);
if (future.wait_for(timeout) == std::future_status::ready)
answer = future.get();
std::cout << "the answer was: " << answer << std::endl;
exit(0);
}
online compiler: https://rextester.com/GLAZ31262
I would do this by creating separate a thread which calls normal blocking IO functions and pass it a callback function which it would call when it got input. Are you sure you need to do what you said you want to do?
As for outputting information at the same time, what would happen if the user was in the middle of typing some input and you printed something?
I've done this on QNX4.5 that doesn't support threads or Boost by using select. You basically pass select STDIN as the file descriptor to use and select will return when a new line is entered. I've added a simplified example loop below. It's platform independent, at least for Unix like systems. Not sure about Windows though.
while (!g_quit)
{
//we want to receive data from stdin so add these file
//descriptors to the file descriptor set. These also have to be reset
//within the loop since select modifies the sets.
FD_ZERO(&read_fds);
FD_SET(STDIN_FILENO, &read_fds);
result = select(sfd + 1, &read_fds, NULL, NULL, NULL);
if (result == -1 && errno != EINTR)
{
cerr << "Error in select: " << strerror(errno) << "\n";
break;
}
else if (result == -1 && errno == EINTR)
{
//we've received and interrupt - handle this
....
}
else
{
if (FD_ISSET(STDIN_FILENO, &read_fds))
{
process_cmd(sfd);
}
}
}
There is one easy way:
char buffer[512];
int point = 0;
...
while (_kbhit()) {
char cur = _getch();
if (point > 511) point = 511;
std::cout << cur;
if (cur != 13) buffer[point++] = cur;
else{
buffer[point] = '\0';
point = 0;
//Run(buffer);
}
}
No block, all in 1 thread. As for me, this works.
Non-blocking console input C++ ?
Ans: do console IO on a background thread and provide a means of communicating between threads.
Here's a complete (but simplistic) test program that implements async io by deferring the io to a background thread.
the program will wait for you to enter strings (terminate with newline) on the console and then perform a 10-second operation with that string.
you can enter another string while the operation is in progress.
enter 'quit' to get the program to stop on the next cycle.
#include <iostream>
#include <memory>
#include <string>
#include <future>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <deque>
int main()
{
std::mutex m;
std::condition_variable cv;
std::string new_string;
bool error = false;
auto io_thread = std::thread([&]{
std::string s;
while(!error && std::getline(std::cin, s, '\n'))
{
auto lock = std::unique_lock<std::mutex>(m);
new_string = std::move(s);
if (new_string == "quit") {
error = true;
}
lock.unlock();
cv.notify_all();
}
auto lock = std::unique_lock<std::mutex>(m);
error = true;
lock.unlock();
cv.notify_all();
});
auto current_string = std::string();
for ( ;; )
{
auto lock = std::unique_lock<std::mutex>(m);
cv.wait(lock, [&] { return error || (current_string != new_string); });
if (error)
{
break;
}
current_string = new_string;
lock.unlock();
// now use the string that arrived from our non-blocking stream
std::cout << "new string: " << current_string;
std::cout.flush();
for (int i = 0 ; i < 10 ; ++i) {
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << " " << i;
std::cout.flush();
}
std::cout << ". done. next?\n";
std::cout.flush();
}
io_thread.join();
return 0;
}
sample test run:
$ ./async.cpp
first
new string: first 0 1las 2t 3
4 5 6 7 8 9. done. next?
new string: last 0 1 2 3 4 5 6 7 8quit 9. done. next?
ncurses can be a good candidate.
The StdinDataIO class of the BSD-licensed MUSCLE networking library supports non-blocking reads from stdin under Windows, MacOS/X, and Linux/Unix ... you could use that (or just examine the code as an example of how it can be done) if you want.
You can use the tinycon library to do this. Just spawn a tinycon object in a new thread, and you are pretty much done. You can define the trigger method to fire off whatever you'd like when enter is pressed.
You can find it here:
https://sourceforge.net/projects/tinycon/
Also, the license is BSD, so it will be the most permissive for your needs.
libuv is a cross-platform C library for asynchronous I/O. It uses an event loop to do things like read from standard input without blocking the thread. libuv is what powers Node.JS and others.
In a sense, this answer is incomplete. But yet, I think it can be useful even for people who have different platforms or circumstances, giving the idea, what to look for in their platform.
As I just wrote some scripting engine integration into an SDL2 main event loop (which is supposed to read lines from stdin if there are lines to be read), here is how I did it (on linux (debian bullseye 64 bit)). See below.
But even if you are not on linux, but on some other posix system, you can use the equivalent platform APIs of your platform. For example, you can use kqueue on FreeBSD. Or you can consider using libevent for a bit more portable approach (still will not really work on Windows).
This approach might also work on Windows if you do some special fiddling with the rather new-ish ConPTY. In traditional windows console applications, the problem is, that stdin is not a real file handle and as such, passing it to libevent or using IOCP (IO completion ports) on it will not work as expected.
But, this approach should also work on posix systems, if there is redirection at play. As long as there is a file handle available.
So how does it work?
Use epoll_wait() to detect if there is data available on stdin. While consoles can be configured in all sorts of ways, typically, they operate on a line by line basis (should also apply for ssh etc.).
Use your favorite getline() function to read the line from stdin. Which will work, because you know, there is data and it will not block (unless your console is not defaulting to line by line handling).
Rince and repeat.
#include <unistd.h>
#include <sys/epoll.h>
#include <iostream>
#include <string>
#include <array>
using EpollEvent_t = struct epoll_event;
int main(int argc, const char* argv[]) {
//
// create epoll instance
//
int epollfd = epoll_create1(0);
if (epollfd < 0) {
std::cout << "epoll_create1(0) failed!" << std::endl;
return -1;
}
//
// associate stdin with epoll
//
EpollEvent_t ev;
ev.data.ptr = nullptr;
ev.data.fd = STDIN_FILENO; // from unistd.h
ev.data.u32 = UINT32_C(0);
ev.data.u64 = UINT64_C(0);
ev.events = EPOLLIN;
if (epoll_ctl(epollfd, EPOLL_CTL_ADD, STDIN_FILENO, &ev) < 0) {
std::cout
<< "epoll_ctl(epollfd, EPOLL_CTL_ADD, fdin, &ev) failed."
<< std::endl;
return -1;
}
//
// do non-blocking line processing in your free running
// main loop
//
std::array<EpollEvent_t,1> events;
bool running = true;
while (running) {
int waitret = epoll_wait(epollfd,
events.data(),
events.size(),
0); // 0 is the "timeout" we want
if (waitret < 0) {
std::cout << "epoll_wait() failed." << std::endl;
running = false;
}
if (0 < waitret) { // there is data on stdin!
std::string line;
std::getline(std::cin, line);
std::cout
<< "line read: [" << line << "]" << std::endl;
if (line == "quit")
running = false;
}
// ... Do what you usually do in your main loop ...
}
//
// cleanup of epoll etc.
//
close(epollfd);
return 0;
}
You could do:
#include <thread>
#include <chrono>
#include <string>
#include <iostream>
int main() {
std::cout << "Type exit to quit." << std::endl;
// initialize other std::thread handlers here
std::string input;
while (input != "exit") {
std::getline(std::cin, input);
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
std::cout << "Cleaning up and quitting" << std::endl;
return 0;
};
A simple answer with thread/future and reading a single char at a time (you can replace getchar with cin as required)
Timeout is set to zero and a new future is created every time the previous call is completed.
Like cin, getchar requires that the user hits the RETURN key to end the function call.
#include <chrono>
#include <cstdio>
#include <future>
#include <iostream>
#include <thread>
static char get_usr_in()
{
return std::getchar();
}
int main()
{
std::chrono::seconds timeout(0);
std::future<char> future = std::async(std::launch::async, get_usr_in);
char ch = '!';
while(ch!='q') {
if(future.wait_for(timeout) == std::future_status::ready) {
ch = future.get();
if(ch!='q') {
future = std::async(std::launch::async, get_usr_in);
}
if(ch >= '!' && ch <'~')
std::cout << "ch:" << ch << std::endl;
}
std::cout << "." << std::endl;
}
exit(0);
}
Why not use promises?
#include <iostream>
#include <istream>
#include <thread>
#include <future>
#include <chrono>
void UIThread(std::chrono::duration<int> timeout) {
std::promise<bool> p;
std::thread uiWorker([&p]() {
bool running = true;
while(running) {
std::string input;
std::cin >> input;
if(input == "quit") {
p.set_value(true);
running = false;
}
}
});
auto future = p.get_future();
if (future.wait_for(timeout) != std::future_status::ready) {
std::cout << "UI thread timed out" << std::endl;
uiWorker.detach();
return;
}
uiWorker.join();
}
int main()
{
std::thread uiThread(UIThread, std::chrono::seconds(3));
std::cout << "Waiting for UI thread to complete" << std::endl;
uiThread.join();
}
online complier
I searched for examples on how to create a simple multithreaded app that does something similar to this:
#include <iostream>
using namespace std;
int myConcurrentFunction( )
{
while( 1 )
{
cout << "b" << endl;
}
}
int main( )
{
// Start a new thread for myConcurrentFunction
while( 1 )
{
cout << "a" << endl;
}
}
How can I get the above to output a and b "randomly" by starting a new thread instead of just calling myConcurrentFunction normally?
I mean: What is the minimal code for it? Is it really only one function I have to call? What files do I need to include?
I use MSVC 2010, Win32
The easiest is _beginthread. Just focus on how they create the thread in their example, it's not as complicated as it seems at a first glance.
#include <iostream>
#include <process.h>
using namespace std;
void myConcurrentFunction(void *dummy)
{
while( 1 )
{
cout << "b" << endl;
}
}
int main( )
{
_beginthread(myConcurrentFunction, 0, NULL);
while( 1 )
{
cout << "a" << endl;
}
}
It is more complicated than that. For one, the thread function must return a DWORD, and take an LPVOID parameters.
Take a look at the code from MSDN for more details.
BTW, why thread when you just need random sprinkiling of 'a' & 'b'.
int randomSprinkling()
{
char val[2]={'a','b'};
int i = 0;
while( ++i < 100 )
{
std::cout << val[rand()%2] << std::endl;
}
return 0;
}