A C++ question on running 2 processes at a time.
I have a client-server model kind of C++ code. My server will fork for every connection from the client. This is a system that also has a reminder module. This reminder module will need to send an email when, let's say, it counts down from 1000 to 0: when it reaches 0, it will perform its code.
But my server is already running in a while(1) loop. How do I invoke this reminder thing together while not affecting the server listening to connections?
Thanks for all help and suggestions.
You are looking for what is commonly know as threads.
Here is an example using Boost.Thread:
#include <iostream>
#include <boost/thread.hpp>
#include <boost/date_time.hpp>
bool worker_running = true;
void workerFunc() {
while (worker_running) {
boost::posix_time::seconds workTime(3);
// do something
boost::this_thread::sleep(workTime);
}
}
int main(int argc, char* argv[])
{
//before your while loop:
boost::thread workerThread(workerFunc);
//while loop here
worker_running = false;
workerThread.join();
return 0;
}
Related
So I have a c++ program here utilizing wiringPi to sleep a thread until a button press (on a rapsberryPi using the GPIO), but when the button is pressed it can often print the message multiple times. I tried to remedy this by sleeping for a few seconds within the loop but this didn't help leading me to believe that it has something to do with how the interrupt generation calls the function. Any advice for how I can solve this so the function is only ran once per button press?
#include <stdlib.h>
#include <iostream>
#include <wiringPi.h>
#include <unistd.h>
void printMessage(void) {
std::cout << "Button pressed! hooray" << std::endl;
}
int main(int argc, char const *argv[]) {
wiringPiSetup();
while(true) {
wiringPiISR(3, INT_EDGE_FALLING, &printMessage);//3 is the wiringPi pin #
sleep(3);
}
}
I think you only have to set the ISR once (call wiringPiISR once). After that just sleep forever (while(1)sleep(10);). You seem to have debounced your button using a print statement. Debouncing can often be a matter of timing, and printing takes a few microseconds causing the button to be "sort of" debounced. It can however still do some bouncing
For more debouncing info see this SO page
I am not familiar with the Raspberry-Pi, but if the code can directly sense the button state (instead of using a triggered interrupt) do something like this to react only on the enabling transition:
int main (...)
{
writingPiSetup ();
bool last_state = false;
while (true)
{
bool this_state = wiringPiDigital (3); // use correct function name
if (last_state == false && this_state == true) // button freshly pressed
{
std::cout << "Button freshly pressed" << std::endl;
}
last_state = this_state;
}
}
However, it is quite possible that the hardware is not debounced. So inserting a little bit of delay might be called for. I would experiment with delays in the 10 to 100 millisecond range depending on the particulars of the application.
I need to port a multiprocess application that uses the Windows API functions SetEvent, CreateEvent and WaitForMultipleObjects to Linux. I have found many threads concerning this issue, but none of them provided a reasonable solution for my problem.
I have an application that forks into three processes and manages thread workerpool of one process via these Events.
I had multiple solutions to this issue. One was to create FIFO special files on Linux using mkfifo on linux and use a select statement to awaken the threads. The Problem is that this solution will operate differently than WaitForMultipleObjects. For Example if 10 threads of the workerpool will wait for the event and I call SetEvent five times, exactly five workerthreads will wake up and do the work, when using the FIFO variant in Linux, it would wake every thread, that i in the select statement and waiting for data to be put in the fifo. The best way to describe this is that the Windows API kind of works like a global Semaphore with a count of one.
I also thought about using pthreads and condition variables to recreate this and share the variables via shared memory (shm_open and mmap), but I run into the same issue here!
What would be a reasonable way to recreate this behaviour on Linux? I found some solutions doing this inside of a single process, but what about doing this with between multiple processes?
Any ideas are appreciated (Note: I do not expect a full implementation, I just need some more ideas to get myself started with this problem).
You could use a semaphore (sem_init), they work on shared memory. There's also named semaphores (sem_open) if you want to initialize them from different processes. If you need to exchange messages with the workers, e.g. to pass the actual tasks to them, then one way to resolve this is to use POSIX message queues. They are named and work inter-process. Here's a short example. Note that only the first worker thread actually initializes the message queue, the others use the attributes of the existing one. Also, it (might) remain(s) persistent until explicitly removed using mq_unlink, which I skipped here for simplicity.
Receiver with worker threads:
// Link with -lrt -pthread
#include <fcntl.h>
#include <mqueue.h>
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
void *receiver_thread(void *param) {
struct mq_attr mq_attrs = { 0, 10, 254, 0 };
mqd_t mq = mq_open("/myqueue", O_RDONLY | O_CREAT, 00644, &mq_attrs);
if(mq < 0) {
perror("mq_open");
return NULL;
}
char msg_buf[255];
unsigned prio;
while(1) {
ssize_t msg_len = mq_receive(mq, msg_buf, sizeof(msg_buf), &prio);
if(msg_len < 0) {
perror("mq_receive");
break;
}
msg_buf[msg_len] = 0;
printf("[%lu] Received: %s\n", pthread_self(), msg_buf);
sleep(2);
}
}
int main() {
pthread_t workers[5];
for(int i=0; i<5; i++) {
pthread_create(&workers[i], NULL, &receiver_thread, NULL);
}
getchar();
}
Sender:
#include <fcntl.h>
#include <stdio.h>
#include <mqueue.h>
#include <unistd.h>
int main() {
mqd_t mq = mq_open("/myqueue", O_WRONLY);
if(mq < 0) {
perror("mq_open");
}
char msg_buf[255];
unsigned prio;
for(int i=0; i<255; i++) {
int msg_len = sprintf(msg_buf, "Message #%d", i);
mq_send(mq, msg_buf, msg_len, 0);
sleep(1);
}
}
I would like to create a c++ webserver that will perform a task for each user that lands on my website. Since the task might be computationally heavy (for now just a long sleep), I'd like to handle each user on a different thread. I'm using mongoose to set up a webserver.
The different processes (in my code below just one, aka server1) are set up correctly and seem to function correctly. However, the threads seem to be queuing one after the other so if 2 users hit the end point, the second user must wait until the first user finishes. What am I missing? Do the threads run out of scope? Is there a "thread-manager" that I should be using?
#include "../../mongoose.h"
#include <unistd.h>
#include <iostream>
#include <stdlib.h>
#include <thread>
//what happens whenever someone lands on an endpoint
void myEvent(struct mg_connection *conn){
//long delay...
std::thread mythread(usleep, 2*5000000);
mythread.join();
mg_send_header(conn, "Content-Type", "text/plain");
mg_printf_data(conn, "This is a reply from server instance # %s",
(char *) conn->server_param);
}
static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
if (ev == MG_REQUEST) {
myEvent(conn);
return MG_TRUE;
} else if (ev == MG_AUTH) {
return MG_TRUE;
} else {
return MG_FALSE;
}
}
static void *serve(void *server) {
for (;;) mg_poll_server((struct mg_server *) server, 1000);
return NULL;
}
int main(void) {
struct mg_server *server1;
server1 = mg_create_server((void *) "1", ev_handler);
mg_set_option(server1, "listening_port", "8080");
mg_start_thread(serve, server1);
getchar();
return 0;
}
Long running requests should be handled like this:
static void thread_func(struct mg_connection *conn) {
sleep(60); // simulate long processing
conn->user_data = "done"; // Production code must not do that.
// Other thread must never access connection
// structure directly. This example is just
// for demonstration.
}
static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
switch (ev) {
case MG_REQUEST:
conn->user_data = "doing...";
spawn_thread(thread_func, conn);
return MG_MORE; // Important! Signal Mongoose we are not done yet
case MG_POLL:
if (conn->user_data != NULL && !strcmp(conn->user_data, "done")) {
mg_printf(conn, "HTTP/1.0 200 OK\n\n Done !");
return MG_TRUE; // Signal we're finished. Mongoose can close this connection
}
return MG_FALSE; // Still not done
Caveat: I'm not familiar with mongoose
My assumptions:
The serve function is polling for incoming connections
If the thread executing mg_poll_server is the same thread that triggers the call to ev_handler then your problem is the fact that ev_handler calls myEvent which starts a long running operation and blocks the thread (i.e., by calling join). In this case you're also blocking the thread which is handling the incoming connections (i.e., A subsequent client must wait for the first client to finish their work), which seems is the behavior you describe seeing.
I'm not sure what the real task is supposed to do so I can't say for sure how you should fix this. Perhaps in your use-case it may be possible to call detach otherwise you might keep track of executing threads and defer calling join on them until the server is shutdown.
James Adkison is absolutely right. So, if instead the beginning of the code looks like this:
void someFunc(struct mg_connection *conn){
usleep(2*5000000);
std::cout << "hello!" << std::endl;
std::cout<< "This finished from server instance #"<<conn<<std::endl;
mg_send_header(conn, "Content-Type", "application/json");
mg_printf_data(conn, "{\"message\": \"This is a reply from server instance # %s\"}",
// (char *) conn->server_param);
}
void myEvent(struct mg_connection *conn){
std::thread mythread(someFunc,conn);
mythread.detach();
std::cout<< "This is a reply from server instance #"<<(char *) conn->server_param<<std::endl;
}
static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
if (ev == MG_REQUEST) {
myEvent(conn);
return MG_TRUE;
} else if (ev == MG_AUTH) {
//.... exactly as before
//....
then the program works. Basically the difference is replacing .join() with .detach(). someFunc is running now in parallel for 2 users -- so that's great!. Thanks!
I've searched the internet for a while now and found different solutions but then all don't really work or are to complicated for my use.
I used C++ until 2 years ago so it might be a bit rusty :D
I'm currently writing a program that posts data to an URL. It only posts the data nothing else.
For posting the data I use curl, but it blocks the main thread and while the first post is still running there will be a second post that should start.
In the end there are about 5-6 post operations running at the same time.
Now I want to push the posting with curl into another thread. One thread per post.
The thread should get a string parameter with the content what to push.
I'm currently stuck on this. Tried the WINAPI for windows but that crashes on reading the parameter. (the second thread is still running in my example while the main thread ended (waiting on system("pause")).
It would be nice to have a multi plattform solution, because it will run under windows and linux!
Heres my current code:
#define CURL_STATICLIB
#include <curl/curl.h>
#include <curl/easy.h>
#include <cstdlib>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#if defined(WIN32)
#include <windows.h>
#else
//#include <pthread.h>
#endif
using namespace std;
void post(string post) { // Function to post it to url
CURL *curl; // curl object
CURLcode res; // CURLcode object
curl = curl_easy_init(); // init curl
if(curl) { // is curl init
curl_easy_setopt(curl, CURLOPT_URL, "http://10.8.27.101/api.aspx"); // set url
string data = "api=" + post; // concat post data strings
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data.c_str()); // post data
res = curl_easy_perform(curl); // execute
curl_easy_cleanup(curl); // cleanup
} else {
cerr << "Failed to create curl handle!\n";
}
}
#if defined(WIN32)
DWORD WINAPI thread(LPVOID data) { // WINAPI Thread
string pData = *((string*)data); // convert LPVOID to string [THIS FAILES]
post(pData); // post it with curl
}
#else
// Linux version
#endif
void startThread(string data) { // FUnction to start the thread
string pData = data; // some Test
#if defined(WIN32)
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)thread, &pData, 0, NULL); // Start a Windows thread with winapi
#else
// Linux version
#endif
}
int main(int argc, char *argv[]) {
// The post data to send
string postData = "test1234567890";
startThread(postData); // Start the thread
system("PAUSE"); // Dont close the console window
return EXIT_SUCCESS;
}
Has anyone a suggestion?
Thanks for the help!
Consider using Boost.Thread or the new C++11 threading facilities (like std::thread etc.).
Some remarks to the code of the initial question:
If staying away from std::thread or boost::thread, use _beginthreadex(..) instead of CreateThread(..) because the latter one can cause resource leaks if used with certain functions of the C runtime.
When using CreateThread(..), a cast to LPTHREAD_START_ROUTINE is not required if the signature of the passed function is correct. So casting it is simply wrong.
The were already some remarks about the lifetime of stack allocated variables and what happens if the address of these are passed to a thread function.
Don't use system("PAUSE") in order to keep the code protable. Instead use the following snippet:
void wait_for_key_press()
{
std::cin.clear();
std::cin.ignore(std::cin.rdbuf()->in_avail());
std::cin.get();
}
Use std::thread for threads. It's a relatively new thing, part of the newest C++11 standard, but it will probably be the most portable way to do threads in the near future.
See how easy it is to make 5 threads that will busy-wait (unless optimized by the compiler):
#include<thread>
#include<vector>
int main()
{
std::vector<std::thread> threads;
for (int i=0; i< 5; i++)
{
threads.push_back(std::thread([] () {
for (long long j=0; j < 1000000000000LL; j++) ;
}));
}
for (auto & thread : threads)
{
thread.join();
}
}
You might want to avoid multi-threading by using libcurl 's multi-operations interface, which enables you to run several concurrent HTTP requests in the same (single) thread.
I'm using gSoap to write a webservice. It's running as a console application. In all gSoap examples I see, that requests are dispatched in infinite loop like for(;;;) even in multi-threaded version.
But how can I make my webservice to terminate gracefully when, say, user presses space on the console?
Preferably:
stop accepting new connections;
Serve existing ones;
Exit from application
The only solution I came up so far is using timeouts
soap->recv_timeout = 20;
soap->send_timeout = 20;
soap->connect_timeout = 5;
soap->accept_timeout = 5;
Then all blocking functions return periodically. But this is not ideal for me, because I want to be able to terminate the app quickly even if there is an ongoing transmission, but at the same time, don't want to compromise reliability on a slow/flaky connection (it's an embedded device connected via GPRS).
The section 7.2.4 How to Create a Multi-Threaded Stand-Alone Service in the documentation has example code for writing an accept loop. You need to write your own accept loop and add signal handling so it responds to Ctrl-C.
stop accepting new connections:
Leave the loop so you stop calling accept.
Serve existing ones:
The threads need to inform you when they are finished, so you can exit when the number of active clients is zero. (boost::thead_group has a join_all which does exactly that.)
Exit from application:
What you need to do is register signal handler so when you terminate your application using Ctrl + C, it calls you registered function where you can gracefully terminates.
e.g
class gsoap_test {
public:
void start() {
running_ = true;
while(running_) {
//gsoap threads
}
//stop and cleanup
}
void stop() {
running_ = false;
}
private:
bool running_;
};
//global variable
gsoap_test gsoap;
void sighandler(int sig)
{
std::cout<< "Signal caught..." << std::endl;
//Stop gracefully here
gsoap.stop();
exit(0);
}
int main(int argc, char** argv) {
//register signal
signal(SIGABRT, &sighandler);
signal(SIGTERM, &sighandler);
signal(SIGINT, &sighandler);
gsoap.start();
return EXIT_SUCCESS;
}