1. Links
bind
http://www.boost.org/doc/libs/1_49_0/libs/bind/bind.html
| TCP | UDP |
| Reliability: TCP is connection-oriented protocol. When a file or message send it will get delivered unless connections fails. If connection lost, the server will request the lost part. There is no corruption while transferring a message. | Reliability: UDP is connectionless protocol. When you a send a data or message, you don't know if it'll get there, it could get lost on the way. There may be corruption while transferring a message. |
| Ordered: If you send two messages along a connection, one after the other, you know the first message will get there first. You don't have to worry about data arriving in the wrong order. | Ordered: If you send two messages out, you don't know what order they'll arrive in i.e. no ordered |
| Heavyweight: - when the low level parts of the TCP "stream" arrive in the wrong order, resend requests have to be sent, and all the out of sequence parts have to be put back together, so requires a bit of work to piece together. | Lightweight: No ordering of messages, no tracking connections, etc. It's just fire and forget! This means it's a lot quicker, and the network card / OS have to do very little work to translate the data back from the packets. |
| Streaming: Data is read as a "stream," with nothing distinguishing where one packet ends and another begins. There may be multiple packets per read call. | Datagrams: Packets are sent individually and are guaranteed to be whole if they arrive. One packet per one read call. |
| Examples: World Wide Web (Apache TCP port 80), e-mail (SMTP TCP port 25 Postfix MTA), File Transfer Protocol (FTP port 21) and Secure Shell (OpenSSH port 22) etc. | Examples: Domain Name System (DNS UDP port 53), streaming media applications such as IPTV or movies, Voice over IP (VoIP), Trivial File Transfer Protocol (TFTP) and online multiplayer games etc |
BOOL CreateTimerQueueTimer(PHANDLE phNewTimer, HANDLE TimerQueue ,
WAITORTIMERCALLBACK Callback, PVOID Parameter, DWORD DueTime,
DWORD Period, ULONG Flags);
phNewTimer - Pointer to a handle; this is an out valueTimerQueue - Timer queue handle. For the default timer queue, NULLCallback - Pointer to the callback functionParameter - Value passed to the callback functionDueTime - Time (milliseconds), before the timer is set to the signaled state for the first time Period - Timer period (milliseconds). If zero, timer is signaled only onceFlags - One or more of the next values (table taken from MSDN):WT_EXECUTEINTIMERTHREAD |
The callback function is invoked by the timer thread itself. This flag should be used only for short tasks or it could affect other timer operations. |
WT_EXECUTEINIOTHREAD |
The callback function is queued to an I/O worker thread. This flag should be used if the function should be executed in a thread that waits in an alertable state. The callback function is queued as an APC. Be sure to address reentrancy issues if the function performs an alertable wait operation. |
WT_EXECUTEINPERSISTENTTHREAD |
The callback function is queued to a thread that never terminates. This flag should be used only for short tasks or it could affect other timer operations. Note that currently no worker thread is persistent, although no worker thread will terminate if there are any pending I/O requests. |
WT_EXECUTELONGFUNCTION |
Specifies that the callback function can perform a long wait. This flag helps the system to decide if it should create a new thread. |
WT_EXECUTEONLYONCE |
The timer will be set to the signaled state only once. |
VOID CALLBACK WaitOrTimerCallback(PVOID lpParameter, BOOLEAN TimerOrWaitFired);
lpParameter - Pointer to user-defined dataTimerOrWaitFired - always TRUE for timer callbacksBOOL DeleteTimerQueueTimer(HANDLE TimerQueue, HANDLE Timer, HANDLE CompletionEvent);
TimerQueue - A handle to the (default) timer queueTimer - A handle to the timerCompletionEvent - A handle to an optional event to be
signaled when the function is successful and all callback functions have
completed. Can be NULL.void CTimersDlg::OnButtonBegin()
{
.
.
.
// create the timer
BOOL success = ::CreateTimerQueueTimer(
&m_timerHandle,
NULL,
TimerProc,
this,
0,
elTime,
WT_EXECUTEINTIMERTHREAD);
}
void CTimersDlg::OnButtonStop()
{
// destroy the timer
DeleteTimerQueueTimer(NULL, m_timerHandle, NULL);
CloseHandle (m_timerHandle);
}
void CTimersDlg::QueueTimerHandler() // called every elTime milliseconds
{
// do what you want to do, but quickly
.
.
.
}
void CALLBACK TimerProc(void* lpParametar,
BOOLEAN TimerOrWaitFired)
{
// This is used only to call QueueTimerHandler
// Typically, this function is static member of CTimersDlg
CTimersDlg* obj = (CTimersDlg*) lpParametar;
obj->QueueTimerHandler();
}
As you can see, queue timers are pretty easy to use. I can also add that they are very accurate, and "resource friendly". __cdecl is the default calling convention for C and C++
programs. The advantage of this calling convetion is that it allows
functions with a variable number of arguments to be used. The
disadvantage is that it creates larger executables. __stdcall is used to call Win32 API functions. It does not allow functions to have a variable number of arguments. __fastcall attempts to put arguments in registers, rather than on the stack, thus making function calls faster. Thiscall calling convention is the default calling convention used by C++ member functions that do not use variable arguments. #include <cstdio>#include <iostream>#include "boost/interprocess/sync/interprocess_mutex.hpp"#include "boost/interprocess/sync/scoped_lock.hpp"#include "boost/interprocess/shared_memory_object.hpp"#include "boost/interprocess/mapped_region.hpp"#include "boost/thread/thread.hpp"using namespace boost::interprocess;namespace{ const char* MY_SHARED = "MySharedMemory"; class SharedMemoryLog // 1. { private: enum { NUM_ITEMS = 10, LINE_SIZE = 100 }; boost::interprocess::interprocess_mutex mutex_; char items[NUM_ITEMS][LINE_SIZE]; int curLine_; bool done_; public: SharedMemoryLog() : curLine_(0), done_(false) {} void push_line(const char* id, int index) { scoped_lock<interprocess_mutex> lock(mutex_); std::sprintf(items[(curLine_++) % SharedMemoryLog::NUM_ITEMS], "%s_%d", id, index); std::cout << "Inserting item " << id << ' ' << index << std::endl; } void dump() { scoped_lock<interprocess_mutex> lock(mutex_); for(int i = 0; i < NUM_ITEMS; ++i) std::cout << items[i] << std::endl; } void done() { scoped_lock<interprocess_mutex> lock(mutex_); done_ = true; } bool isDone() { scoped_lock<interprocess_mutex> lock(mutex_); return done_; } }; class ShMemManager // 2. { private: std::string name_; bool create_; shared_memory_object shm_; mapped_region region_; SharedMemoryLog* sml_; void remove() { shared_memory_object::remove(name_.c_str()); } public: ShMemManager(const char* name, bool create = true) : name_(name), create_(create) { if(create_) { remove(); shared_memory_object shm(create_only, name_.c_str(), read_write); shm.truncate(sizeof(SharedMemoryLog)); shm_.swap(shm); } else { shared_memory_object shm(open_only, name_.c_str(), read_write); shm_.swap(shm); } mapped_region region(shm_, read_write); region_.swap(region); void* addr = region_.get_address(); sml_ = create_ ? new (addr) SharedMemoryLog : static_cast<SharedMemoryLog*>(addr); } ~ShMemManager() { remove(); } SharedMemoryLog* getMemory() { return sml_; } };}void ip07a() // 4.{ std::cout << "Starting master process ..." << std::endl; try { ShMemManager smm(MY_SHARED); SharedMemoryLog* data = smm.getMemory(); for(int i = 0; i < 7; ++i) { data->push_line("master", i); boost::this_thread::sleep(boost::posix_time::milliseconds(1000)); } std::cout << "Master dumps data:" << std::endl; data->dump(); while(true) { if(data->isDone()) { std::cout << "Master sees that the other process is done" << std::endl; break; } std::cout << "Master waits for the other process" << std::endl; boost::this_thread::sleep(boost::posix_time::milliseconds(1000)); } std::cout << "Master dumps again the data:" << std::endl; data->dump(); } catch(interprocess_exception& ex) { std::cout << ex.what() << std::endl; return; } std::cout << "Master execution completed" << std::endl;}void ip07b(const char* id) // 5.{ std::cout << "Process " << id << " started" << std::endl; try { ShMemManager smm(MY_SHARED, false); SharedMemoryLog* data = smm.getMemory(); for(int i = 0; i < 7; ++i) { data->push_line(id, i); boost::this_thread::sleep(boost::posix_time::milliseconds(1000)); } data->done(); std::cout << id << " dumps data:" << std::endl; data->dump(); } catch(interprocess_exception& ex) { std::cout << ex.what() << std::endl; return; } std::cout << "Process " << id << " done" << std::endl;} |