C++ WIN32: Short multitasking example - c++

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;
}

Related

How do I use threading in this situation?

How can i make a small program that prints something endlessly, but I can still use the standard input to write and display something whenever I want?
I found this example, but it terminates after just 2 inputs (and I want to input something multiple times, not just 2).
#include <iostream>
#include <thread>
#include <chrono>
#include <string>
using std::cout;
using std::cin;
using std::thread;
using std::string;
using std::endl;
int stopflag = 0;
void input_func()
{
while (true && !stopflag)
{
string input;
cin >> input;
cout << "Input: " << input << endl;
}
}
void output_func()
{
while (true && !stopflag)
{
std::this_thread::sleep_for(std::chrono::seconds(1));
cout << "Output thread\n";
}
}
int main()
{
while (1)
{
thread inp(input_func);
thread outp(output_func);
std::this_thread::sleep_for(std::chrono::seconds(5));
stopflag = 1;
outp.join();
cout << "Joined output thread\n";
inp.join();
}
cout << "End of main, all threads joined.\n";
return 0;
}
Just remove the line stopflag = 1. But also, if you want to print the lines you need to add synchronization to modify flag and also printing. Because only one thread should write to console and one time. Don't forget to add flush, as it will not print all text always.

How can i use sigaction() to intercept SIGINT?

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).

C++ : How do I execute a function after several seconds?

Firstly, I'm using VS2008 (doesn't support C++11). I can't upgrade and need to use native libraries only because it needs to be compiled on another persons' compiler which I don't have control over.
I would like to run the code automatically after 5 seconds without having to poll how many seconds have elapsed.
This is my incomplete code
#include <windows.h>
#include <iostream>
void runMeAfterFiveSeconds(){
cout<<"I'm activated!"<<endl;
}
void main(){
while(1){
cout<<"hello there!"<<endl;
Sleep(2000);
}
}
Example output
hello there!
hello there! //after 2 seconds
hello there! //after 4 seconds
I'm activated! //after 5 seconds
hello there! //after 6 seconds
hello there! //after 8 seconds
hello there! //after 10 seconds
I'm activated! //after 10 seconds
...
This example shows how to do it using a very simple scheduling algorithm. No spawning of additional threads is required.
#include <stdio.h>
#include <windows.h>
int main(int argc, char ** argv)
{
DWORD now = timeGetTime();
DWORD nextPrintHelloThereTime = now;
DWORD nextPrintImActivatedTime = now+5000;
while(1)
{
now = timeGetTime();
DWORD nextEventTime = (nextPrintHelloThereTime < nextPrintImActivatedTime) ? nextPrintHelloThereTime : nextPrintImActivatedTime;
DWORD millisecondsToSleep = nextEventTime-now;
Sleep(millisecondsToSleep);
now = timeGetTime();
if (now >= nextPrintHelloThereTime)
{
printf("hello there!\n");
nextPrintHelloThereTime += 2000;
}
if (now >= nextPrintImActivatedTime)
{
printf("I'm activated!\n");
nextPrintImActivatedTime += 5000;
}
}
}
It really depends on what code you want to execute and how you want it to be executed.
The very simple way of doing so would be creating a separate thread and Sleep() in it.
So, since you cannot upgrade from Visual Studio 2008 (which, if I remember correctly, does not support C++11), you have to use either native Windows threads or some library implementation like Boost.Thread.
To look up how to use Windows threads, see MSDN documentation on _beginthreadex() function.
A short tutorial about Boost.Thread can bee seen here.
Quick examples of both, taken directly from the links I provided:
1) Windows threads:
// crt_begthrdex.cpp
// compile with: /MT
#include <windows.h>
#include <stdio.h>
#include <process.h>
unsigned Counter;
unsigned __stdcall SecondThreadFunc( void* pArguments )
{
printf( "In second thread...\n" );
while ( Counter < 1000000 )
Counter++;
_endthreadex( 0 );
return 0;
}
int main()
{
HANDLE hThread;
unsigned threadID;
printf( "Creating second thread...\n" );
// Create the second thread.
hThread = (HANDLE)_beginthreadex( NULL, 0, &SecondThreadFunc, NULL, 0, &threadID );
// Wait until second thread terminates. If you comment out the line
// below, Counter will not be correct because the thread has not
// terminated, and Counter most likely has not been incremented to
// 1000000 yet.
WaitForSingleObject( hThread, INFINITE );
printf( "Counter should be 1000000; it is-> %d\n", Counter );
// Destroy the thread object.
CloseHandle( hThread );
}
2) Boost.Thread:
struct callable
{
void operator()();
};
boost::thread copies_are_safe()
{
callable x;
return boost::thread(x);
} // x is destroyed, but the newly-created thread has a copy, so this is OK
In the second example, you could as well have used a plain function pointer as boost::thread constructor argument. Moreover, you could use a pointer to function with multiple arguments - a luxury Windows API's threads do not provide.
You're probably just going to need to create a thread like so:
#include <windows.h>
#include <iostream>
#include <thread>
void runMeAfterFiveSeconds(){
while(true){
sleep(5000);
cout<<"I'm activated!"<<endl;
}
}
void main(){
std::thread th(runMeAfterFiveSeconds);
while(1){
cout<<"hello there!"<<endl;
Sleep(2000);
}
}
You're going to have to either make a thread (Coding Orange's answer, probably the better way), or just write it all out.
void runMeAfterFiveSeconds(){
cout << "I'm activated!" <<endl;
}
void main(){
while(1){
cout << "hello there!" << endl;
Sleep(2000);
cout << "hello there!" << endl;
Sleep(3000);
runMeAfterFiveSeconds();
Sleep(1000);
cout << "hello there!" << endl;
Sleep(2000);
cout << "hello there!" << endl;
Sleep(2000);
cout << "hello there!" << endl;
runMeAfterFiveSeconds();
}
}

Why joyGetPos works, and joyGetPosEx does not? [duplicate]

This question already has an answer here:
joyGetPosEx returns 165 in C#
(1 answer)
Closed 8 years ago.
Currently writing a small program using a joystick, I struggle to understand why the joyGetPos() works, while joyGetPosEx() does not.
I did some basic program using C++, and it's my first project using a joystick.
Platform: windows 7 64 bit
Joystick: http://www.thrustmaster.com/en_UK/products/hotas-cougar
Doc on the joystick functions: http://msdn.microsoft.com/en-us/library/windows/desktop/dd757121(v=vs.85).aspx
Code for JOYINFO
#include <iostream>
#include <stdio.h>
#include <string>
#include <Windows.h>
int main( int argc, char** argv )
{
while ( true )
{
unsigned int num_dev = joyGetNumDevs();
if ( 0 == num_dev )
{
std::cout << "[ERROR ] num_dev == 0" << std::endl;
}
/* JOYINFO */
// retreiving the joystick values
JOYINFO joyinfo;
MMRESULT joygetpos_result = joyGetPos( JOYSTICKID1, &joyinfo );
// if tested, joygetpos_result does not produce any error
// values change when playing with the stick
std::cout << "joinfo.wXpos = " << joinfo.wXpos << std::endl;
std::cout << "joinfo.wYpos = " << joinfo.wYpos << std::endl;
}
}
This version is quite well, but the big grey hat and 4 buttons out of 18 do not work.
Code for JOYINFOEX
#include <iostream>
#include <stdio.h>
#include <string>
#include <Windows.h>
int main( int argc, char** argv )
{
while ( true )
{
unsigned int num_dev = joyGetNumDevs();
if ( 0 == num_dev )
{
std::cout << "[ERROR ] num_dev == 0" << std::endl;
}
/* JOYINFOEX */
// retreiving the joystick values
JOYINFOEX joyinfoex;
MMRESULT joygetposex_result = joyGetPosEx( JOYSTICKID1, &joyinfoex);
// error always produced
if ( joygetposex_result == JOYERR_PARMS)
{
std::cout << "[ERROR ] JOYERR_PARMS" << std::endl;
}
// values does not change when playing with the stick
std::cout << "joinfoex.dwXpos = " << joinfoex.dwXpos << std::endl;
std::cout << "joinfoex.dwYpos = " << joinfoex.dwYpos << std::endl;
}
This second version is always producing the JOYERR_PARMS error. I tried to change the JOYSTICKID1 from 1 to 15, but without any success. I think I am not using correctly the windows functions, but unfortunately I am not able to understand the correct way to use it.
Did you face the same problem? Am I using the good API to use such joystick ?
Thanks for your help.
From the MSDN page on joyGetPosEx:
Pointer to a JOYINFOEX structure that contains extended position information and button status of the joystick. You must set the dwSize and dwFlags members or joyGetPosEx will fail.
You will need to populate your variable joyinfoex with the size and flags.
joyinfoex.dwSize = sizeof(joyinfoex);
joyinfoex.dwFlags = JOY_RETURNALL;

How to check the class id is registered or not?

Hi i am checking the GUID of SqlClass which is in my Test.dll But it does not give success it failed with value... Whatis wrong in this code.
#include <windows.h>
#include <iostream>
using namespace std;
int main() {
HKEY hk;
long n = RegOpenKeyEx(HKEY_CLASSES_ROOT,TEXT("\\CLSID\\SqlClass"),
0,KEY_QUERY_VALUE, &hk );"
if ( n == ERROR_SUCCESS ) {
cout << "OK" << endl;
}
else {
cout << "Failed with value " << n << endl;
}
}
I tried like this also RegOpenKeyEx(HKEY_CLASSES_ROOT,TEXT("\CLSID\46A951AC-C2D9-48e0-97BE-91F3C9E7B065"),
0,KEY_QUERY_VALUE, &hk )
THIS CODE WORKS FINE
#include < windows.h >
# include < iostream >
using namespace std;
int main() {
HKEY hk;
long n = RegOpenKeyEx(HKEY_CLASSES_ROOT,
TEXT("\\CLSID\\{46A951AC-C2D9-48e0-97BE-91F3C9E7B065}"),
0,KEY_QUERY_VALUE, &hk );"
if ( n == ERROR_SUCCESS ) {
cout << "OK" << endl;
}
else {
cout << "Failed with value " << n << endl;
}
}
I've never seen anything other than a GUID under CLSID, so the key probably doesn't exist. Look in that node under regedit to see what I mean.
What was the failure code, n? You can look this up in two ways
Put the number into the "Error Lookup" tool in Visual Studio's Tools menu.
Call FormatMessage on n, which gives you the text associated with that error.