1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
|
// As libthreadar may not be installed on the system (this sample code
// is part of libthreader distribution) we include the libthreadar
// with explicit path. In your program you should rather use the following
// directive: #include <libthreadar/libthreadar.hpp>
#include "../../src/libthreadar.hpp"
extern "C"
{
#include <string.h>
#include <unistd.h>
} // end of extern "C"
#include <string>
#include <iostream>
using namespace std;
class my_thread: public libthreadar::thread
{
public:
// constructor
my_thread(const string & name): channel(10, 100) { my_name = name; counter = 0; };
// variable my_name is accessed by both calling and inner threads but is read-only, not using mutex here
const string & get_name() const { return my_name; };
void send_message(const string & msg)
{
if(is_running())
{
char *ptr;
unsigned int size;
channel.get_block_to_feed(ptr, size);
try
{
strncpy(ptr, msg.c_str(), size);
ptr[size - 1] = '\0';
if(msg.size() < size)
size = msg.size();
}
catch(...)
{
channel.feed_cancel_get_block(ptr);
throw;
}
channel.feed(ptr, size);
}
else
cout << "Warning: inner thread is not running! Will not send a message." << endl;
}
protected:
virtual void inherited_run() override
{
char *ptr;
unsigned int size;
channel.reset();
do
{
channel.fetch(ptr, size);
try
{
if(size > 1) // 1 char for the ending zero of the string
cout << my_name << "[" << counter++ << "] " << ptr << endl;
else
cout << my_name << " received void message, ending thread normally" << endl;
}
catch(...)
{
channel.fetch_push_back(ptr, size);
throw;
}
channel.fetch_recycle(ptr);
}
while(size > 1);
}
private:
string my_name;
unsigned int counter;
libthreadar::fast_tampon<char> channel; // fetcher is the inner thread, feeder is the calling thread
};
int main()
{
my_thread t1("Zorro");
string msg;
t1.run(); // a separated thread should run shortly
while(! t1.is_running())
sleep(1);
cout << "type any string then return, the word \"stop\" ends the process" << endl;
do
{
cin >> msg;
if(msg != "stop")
t1.send_message(msg);
else
t1.send_message("");
}
while(msg != "stop");
cout << "Main thread now waits for child thread to complete" << endl;
t1.join();
return 0;
}
|