Hello, someone can to get me samples of callbacks like producer and consumer.
Thanks in advance.
Printable View
Hello, someone can to get me samples of callbacks like producer and consumer.
Thanks in advance.
dmf,
Callbacks are a class of functions. There are many kinds of callbacks in all different types of programming. In general, a callback function is used as a delayed reaction to some kind of input or after some result.
Callback techniques are often used in multi-process or multi-threaded applications in order to provide communication mechanisms among threads and processes.
The example below might be a little bit tough to understand. But please do take a look. The windows stuff is all standard. It will give you the right ideas. It uses Microsoft compilers in the Win32 API environment. Try to see how the callback works.
Sincerely, Chris.
Code:
#include <iostream>
#include <Windows.h>
static bool b_done = false;
static void callback_calculation_done(void)
{
b_done = true;
}
// Some calculation in some kind of thread process.
DWORD WINAPI thread_do_calculation(LPVOID p = NULL)
{
double hundred_factorial = 2;
for(int i = 3; i <= 100; i++)
{
hundred_factorial *= static_cast<double>(i);
}
// Communicate that the calculation is done using the callback.
callback_calculation_done();
return 0;
}
int main(int argc, char* argv[])
{
SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, FALSE };
DWORD id;
HANDLE h = ::CreateThread(&sa,
0,
thread_do_calculation,
NULL,
THREAD_PRIORITY_NORMAL,
&id);
if(h)
{
while(!b_done)
{
;
}
}
::std::cout << b_done << ::std::endl;
return 0;
}
"callback_calculation_done()" is not a callback function here. " thread_do_calculation()" qualifies as one though not in the traditional sense. A callback function simply refers to a pointer to a function that you hand off to someone else so the function can later be invoked (called back) when something interesting happens. For instance, take a look at the Windows function "EnumWindows()". The first argument is a callback function that "EnumWindows()" will invoke (call back) once for each top-level window on the system. This is what is normally meant by a "callback". BTW, your use of "b_done" to block the main thread is inefficient. You should rely on methods like passing the thread handle to "WaitForSingleObject()" for instance. More importantly, you're accessing a global (static) variable across two threads without providing synchronization control (which is rather harmless in this trivial example but the technique in general is dangerous).Quote:
Originally posted by dude_1967
Code:
#include <iostream>
#include <Windows.h>
static bool b_done = false;
static void callback_calculation_done(void)
{
b_done = true;
}
// Some calculation in some kind of thread process.
DWORD WINAPI thread_do_calculation(LPVOID p = NULL)
{
double hundred_factorial = 2;
for(int i = 3; i <= 100; i++)
{
hundred_factorial *= static_cast<double>(i);
}
// Communicate that the calculation is done using the callback.
callback_calculation_done();
return 0;
}
int main(int argc, char* argv[])
{
SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, FALSE };
DWORD id;
HANDLE h = ::CreateThread(&sa,
0,
thread_do_calculation,
NULL,
THREAD_PRIORITY_NORMAL,
&id);
if(h)
{
while(!b_done)
{
;
}
}
::std::cout << b_done << ::std::endl;
return 0;
}
Yeah Sef, dmf,
I'm sorry. I had forgotten that a central point to the callback function is that a pointer to the callback function is usually passed to some kind of management list for future callback usage.
My example is a bit poor and faulty.
Just think: Function pointer to callback --> Management scheme --> Calls the callback later. This is the general callback stuff.
Sincerely, Chris.
:)
In C++, I prefer to use the Observer pattern:
This can be extended to allow Foo to have a vector of observers (they'd have to be stored as pointers, not references, though). Also Bar can be an observer of more than one class by inheriting from multiple observer interfaces.Code:class FooObserver
{
public:
virtual void OnFooStarted() = 0;
virtual void OnFooDone() = 0;
};
class Foo
{
public:
void DoIt()
{
obs.OnFooStarted();
// do stuff
obs.OnFooDone();
}
Foo(FooObserver& o) : obs(o) {}
private:
FooObserver& obs;
};
class Bar : public FooObserver
{
public:
void OnFooStarted() { /* Do something*/ }
void OnFooDone() { /* Do something */ }
void Something()
{
Foo f(*this);
f.DoIt();
}
};
I find this sample of callbacks, and I ask if not exits another way to do this.
#include <iostream.h>
class Button;
class CdPlayer
{
public:
void buttonPushed(Button* pButton_)
{
if (pButton_ == _pPlayButton)
this->playButtonPushed(pButton_);
else if (pButton_ == _pStopButton)
this->stopButtonPushed(pButton_);
}
void setPlayButton(Button* pButton_) {_pPlayButton = pButton_;}
void setStopButton(Button* pButton_) {_pStopButton = pButton_;}
void playButtonPushed(Button*) {cout << "PLAY" << endl;}
void stopButtonPushed(Button*) {cout << "STOP" << endl;}
private:
Button* _pPlayButton;
Button* _pStopButton;
};
//----------------------------------------
class Button
{
public:
Button(CdPlayer* pCdPlayer_): _pCdPlayer(pCdPlayer_){}
void push() {_pCdPlayer->buttonPushed(this);}
private:
CdPlayer* _pCdPlayer;
};
//----------------------------------------
main()
{
CdPlayer aCdPlayer;
Button playButton(&aCdPlayer);
Button stopButton(&aCdPlayer);
aCdPlayer.setPlayButton(&playButton);
aCdPlayer.setStopButton(&stopButton);
playButton.push();
stopButton.push();
return 0;
}
I don' t know where you found this, but it's a terrible example of anything.
The use of _ to distinguish variables of buttons (preceeding AND trailing) is abysmal and will lead to bugs almost certainly.
Secondly, it's not an example of callbacks. It's a strange example of how to pass an object into another object, and then that other object using it. Nothing unusual at all.
By the way, I program radios that drive CD mechanisms for a living. This is not the way you want to go about this sort of thing. It's almost reminiscent of the Microsoft tuner APIs built into Apollo, sorry, AutoPC, sorry, Windows CE for Automotive.
I suggest looking into good ol' qsort to see what a callback function is all about.
I'm mad because I missed Charlie Brown Halloween this year.
FYI, when passing in a new value or object to take the place of an old one, try giving them meaningful names, then there won't be a conflict that appending or prepending _ gets around.
e.g.
Code:CMyRadio::hereIsANewButtonForYa(CMyButton &theNewMyButton)
{
mMyButton = theNewMyButton
}