The main function is based on libevent, but there is a long run task in the function. So start N treads to run the tasks. Is is this idea OK? And how to use libevent and pthread together in C?
Bumping an old question, may have already been solved. But posting the answer just in case someone else needs it.
Yes, it is okay to do threading in this case. I recently used libevent in pthreads, and it seems to be working just fine. Here's the code :
#include <stdint.h>
#include <pthread.h>
#include <event.h>
void * thread_func (void *);
int main(void)
{
int32_t tid = 0, ret = -1;
struct event_base *evbase;
struct event *timer;
int32_t *t_ret = &ret;
struct timeval tv;
// 1. initialize libevent for pthreads
evthread_use_pthreads();
ret = pthread_create(&tid, NULL, thread_func, NULL);
// check ret for error
// 2. allocate event base
evbase = event_base_new();
// 3. allocate event object
timer = event_new(evbase, -1, EV_PERSIST, callback_func, NULL);
// 4. add event
tv.tv_sec = 0;
tv.tv_usec = 1000;
evtimer_add(timer, &tv);
// 5. start the event loop
event_base_dispatch(evbase); // event loop
// join pthread...
// 6. free resources
event_free(timer);
event_base_free(evbase);
return 0;
}
void * thread_func(void *arg)
{
struct event *ev;
struct event_base *base;
base = event_base_new();
ev = event_new(base, -1, EV_PERSIST, thread_callback, NULL);
event_add(ev, NULL); // wait forever
event_base_dispatch(base); // start event loop
event_free(ev);
event_base_free(base);
pthread_exit(0);
}
As you can see, in my case, the event for the main thread is timer. The base logic followed is as below :
call evthread_use_pthreads() to initialize libevent for pthreads on Linux (my case). For windows evthread_use_window_threads(). Check out the documentation given in event.h itself.
Allocate an event_base structure on global heap as instructed in documentation. Make sure to check return value for errors.
Same as above, but allocate event structure itself. In my case, I am not waiting on any file descriptor, so -1 is passed as argument. Also, I want my event to persist, hence EV_PERSIST . The code for callback functions is omitted.
Schedule the event for execution
Start the event loop
free the resources when done.
Libevent version used in my case is libevent2 5.1.9 , and you will also need libevent_pthreads.so library for linking.
cheers.
That would work.
In the I/O callback function delegates time consuming job to another thread of a thread pool. The exact mechanics depend on the interface of the worker thread or the thread pool.
To communicate the result back from the worker thread to the I/O thread use a pipe. The worker thread writes the pointer to the result object to the pipe and the I/O thread
wakes up and read the pointer from the pipe.
There is a multithreaded libevent example in this blog post:
http://www.roncemer.com/multi-threaded-libevent-server-example
His solution is, to quote:
The solution is to create one libevent event queue (AKA event_base) per active connection, each with its own event pump thread. This project does exactly that, giving you everything you need to write high-performance, multi-threaded, libevent-based socket servers.
NOTE This is for libev not libevent but the idea may apply.
Here I present an example for the community. Please comment and let me know if there are any noticable bugs. This example could include a signal handler for thread termination and graceful exit in the future.
//This program is demo for using pthreads with libev.
//Try using Timeout values as large as 1.0 and as small as 0.000001
//and notice the difference in the output
//(c) 2009 debuguo
//(c) 2013 enthusiasticgeek for stack overflow
//Free to distribute and improve the code. Leave credits intact
//compile using: gcc -g test.c -o test -lpthread -lev
#include <ev.h>
#include <stdio.h> // for puts
#include <stdlib.h>
#include <pthread.h>
pthread_mutex_t lock;
double timeout = 0.00001;
ev_timer timeout_watcher;
int timeout_count = 0;
ev_async async_watcher;
int async_count = 0;
struct ev_loop* loop2;
void* loop2thread(void* args)
{
// now wait for events to arrive on the inner loop
ev_loop(loop2, 0);
return NULL;
}
static void async_cb (EV_P_ ev_async *w, int revents)
{
//puts ("async ready");
pthread_mutex_lock(&lock); //Don't forget locking
++async_count;
printf("async = %d, timeout = %d \n", async_count, timeout_count);
pthread_mutex_unlock(&lock); //Don't forget unlocking
}
static void timeout_cb (EV_P_ ev_timer *w, int revents) // Timer callback function
{
//puts ("timeout");
if(ev_async_pending(&async_watcher)==false){ //the event has not yet been processed (or even noted) by the event loop? (i.e. Is it serviced? If yes then proceed to)
ev_async_send(loop2, &async_watcher); //Sends/signals/activates the given ev_async watcher, that is, feeds an EV_ASYNC event on the watcher into the event loop.
}
pthread_mutex_lock(&lock); //Don't forget locking
++timeout_count;
pthread_mutex_unlock(&lock); //Don't forget unlocking
w->repeat = timeout;
ev_timer_again(loop, &timeout_watcher); //Start the timer again.
}
int main (int argc, char** argv)
{
if (argc < 2) {
puts("Timeout value missing.\n./demo <timeout>");
return -1;
}
timeout = atof(argv[1]);
struct ev_loop *loop = EV_DEFAULT; //or ev_default_loop (0);
//Initialize pthread
pthread_mutex_init(&lock, NULL);
pthread_t thread;
// This loop sits in the pthread
loop2 = ev_loop_new(0);
//This block is specifically used pre-empting thread (i.e. temporary interruption and suspension of a task, without asking for its cooperation, with the intention to resume that task later.)
//This takes into account thread safety
ev_async_init(&async_watcher, async_cb);
ev_async_start(loop2, &async_watcher);
pthread_create(&thread, NULL, loop2thread, NULL);
ev_timer_init (&timeout_watcher, timeout_cb, timeout, 0.); // Non repeating timer. The timer starts repeating in the timeout callback function
ev_timer_start (loop, &timeout_watcher);
// now wait for events to arrive on the main loop
ev_loop(loop, 0);
//Wait on threads for execution
pthread_join(thread, NULL);
pthread_mutex_destroy(&lock);
return 0;
}
Related
How can I exit or stop a thread immediately?
How can I make it stop immediately when the user enters an answer?
I want it to reset for every question.
Here's my code where threading is involved
int q1() {
int timer_start;
char ans[] = "lol";
char user_ans[50];
timer_start = pthread_create( &xtimer,NULL,(void*)timer_func,(void*)NULL);
printf("What is the capital city of Peru?\n");
while(limit){
scanf("%s",user_ans);
if(limit)
{
if(!strcmp(user_ans, ans))
{
// printf("YAY!\n");
score++;
// q2();
}
else
{
game_over();
}
}
}
}
You can simply call pthread_cancel on that thread to exit it. And you can send SIGSTOP/SIGCONT signal via pthread_kill to stop/restart it.
But if all you want is a timer, why must you thread?
Based on your code I can give a simple answer:
In this case do not use threads at all.
You do not need them. Store the start time, let the user answer, check the time again after user gives an answer.
{
time_t startTimeSec = time(NULL);
// answering
time_t endTimeSec = time(NULL);
time_t timeTakenSec = endTime-startTime;
if (timeTaken > 10) {
// do your thing
}
}
To answer your question:
You should use a mutex-protected or volatile variable to asynchronously communicate between threads. Set that variable from one thread and check it in another. Then reset its value and repeat. A simple snippet:
int stopIssued = 0;
pthread_mutex_t stopMutex;
int getStopIssued(void) {
int ret = 0;
pthread_mutex_lock(&stopMutex);
ret = stopIssued;
pthread_mutex_unlock(&stopMutex);
return ret;
}
void setStopIssued(int val) {
pthread_mutex_lock(&stopMutex);
stopIssued = val;
pthread_mutex_unlock(&stopMutex);
}
Using pthread_cancel() is an option, but I would not suggest doing it. You will have to check the threads state after this call returns, since pthread_cancel() does not wait for the actual thread stop. And, which to me is even more important, I consider using it ugly.
Using methods to stop a thread is a brute way.
You should rather politely ask the thread to stop by signalling.
Thereby the thread will have an option to tidy after itself e.g. if it has allocated memory, which it will not have any opportunity to do if the thread is cancelled.
The method is relatively simple and comprises no OS signalling:
define a thread state variable or structure outside the thread. Point to it at the pthread_create and dereference the state variable in the thread.
int thread_state = 0; // 0: normal, -1: stop thread, 1: do something
static void *thread_1 (void *arg)
{
int* pthread_state = arg;
... // initialize the thread locals
while(1)
{
switch( *pthread_state )
{
case 0: // normal thread loop
...
break;
case -1:
... // tidy or whatever is necessary
pthread_exit(0); // exit the thread signalling normal return
break;
case 1: //
... // do something special
break;
}
}
}
pthread_create (&t_1, NULL, thread_1, (void*)&thread_state);
...
thread_state = -1; // signal to the thread to stop
// maybe use pthread_exit(0) to exit main.
// this will leave the threads running until they have finished tidy etc.
It is even possible to communicate with the thread using a structure provided that it is simple 'atomic' variables or a simple handshake mechanism is established. Otherwise it may be necessary to use mutex.
Use pthread_join to wait for threads to terminate.
#Naruil's suggestion to call pthread_cancel() is pretty much the best solution i found, but it won't work if you didn't do the following things.
According to the man-page of pthread_cancel the pthread_cancelibility depend on two thing
thread_cancel_state.
thread_cancel_type.
thread_cancel_state is PTHREAD_CANCEL_ENABLE by default, so our main concern is about the thread_cancel_type, it's default value is type PTHREAD_CANCEL_DEFFERED but we need PTHREAD_CANCEL_ASYNCHRONOUS to set on that thread, which we wan't to cancel.
Following an example given::
#include <stdio.h>
#include <pthread.h>
void *thread_runner(void* arg)
{
//catch the pthread_object as argument
pthread_t obj = *((pthread_t*)arg);
//ENABLING THE CANCEL FUNCTIONALITY
int prevType;
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &prevType);
int i=0;
for( ; i < 11 ; i++)//1 - > 10
{
if(i == 5)
pthread_cancel(obj);
else
printf("count -- %d", i);
}
printf("done");
}
int main(int argc, char *argv[])
{
pthread_t obj;
pthread_create(&obj, NULL, thread_runner, (void*)&obj);
pthread_join(obj, NULL);
return 0;
}
run it using gcc filename.c -lpthread and output the following::
count -- 0
count -- 1
count -- 2
count -- 3
count -- 4
note that the done is never printed because the thread was canceled when the i became 5 & the running thread was canceled. Special thanks #Naruil for the "pthread_cancel" suggestion.
I have made an application that monitors an interface and returns a packets per second reading, how ever when executed it runs fine for about 30 seconds till I open a YouTube page to get the counter running a little high. A couple of seconds later the application freezes and does nothing. This happens in irregular intervals so Im guessing its something with the counting, theres the code, its written in C.
#include <stdio.h>
#include <pcap.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <pthread.h>
void callThreads(u_char *useless, const struct pcap_pkthdr* pkthdr, const u_char* packet);
void *packetcalc(void *threadid);
static struct timespec time1, time2;
static int t = 0, i = 0;
static long rc;
static pthread_t threads[1];
int main(int argc, char *argv[]){
pcap_t* descr;
char errbuf[PCAP_ERRBUF_SIZE];
descr = pcap_open_live("eth0", BUFSIZ, 1, -1, errbuf);
if(descr == NULL){
printf("Error: pcap_open_live()\n");
return 1;
}
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1);
pcap_loop(descr, 0, callThreads, NULL);
return 0;
}
void callThreads(u_char *useless, const struct pcap_pkthdr* pkthdr, const u_char* packet){
if(i >= 2147483647){
//In case i gets full from counting too many packets
i = 0;
time1.tv_sec = 0;
}
++i;
rc = pthread_create(&threads[t], NULL, packetcalc, (void *) t);
}
void *packetcalc(void *threadid){
static int j;
static int temp = 0;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1);
if(temp != time1.tv_sec){
j = (i / time1.tv_sec);
printf("Packets: %d/sec\t(%d)\t(%d)\n", j, i, (int)time1.tv_sec);
temp = time1.tv_sec;
}
pthread_exit(NULL);
}
Edit: Could it also be that I'm running this code in a VM that only has 1 CPU allocated to it due to the multithreading?
You are creating a thread per packet, which is a horrible idea. It should be enough to just print whatever counter you need right out of the callback function you give to pcap_loop(3).
There are several problems with your code. First, you create the threads using the default thread attributes, which means that they are created as joinable threads, i.e. you must call pthread_join() later or the thread control structures would remain lingering around. Hence there is a memory leak in your code. May be you should check the return value from pthread_create in order to detect when an error occurs, e.g. the system was not able to create new threads and your packet counting routine has stopped being invoked. You can also create new threads in detached state using the following code:
pthread_attr_t attr;
pthread_attribute_init(&attr);
pthread_attribute_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_create(&threadid, &attr, packetcalc, (void *) t);
pthread_attribute_destroy(&attr);
Detached threads do not need to be joined later. They release all resources upon thread exit.
Second, you threads use some global variables as if they are private when in reality they are shared. This includes the global time1, as well as the local j and temp, which are declared static and hence are shared among the threads.
Note that creating threads is an expensive operation. While your code waits for pthread_create to finish, new packets may arrive and fill up the circular buffer, used by libpcap, hence you might lose some packets. As a matter of fact, using one thread per packet is a very bad idea. Instead use only two threads - one that runs the pcap loop and one that periodically counts the number of packets and calculates and prints the packet rate.
I am trying to figure out how to get rid of a reliance on the pthread_timedjoin_np because I am trying to build some code on OSX.
Right now I have a Queue of threads that I am popping from, doing that pthread_timedjoin_np and if they dont return, they get pushed back on the queue.
The end of the thread_function that is called for each thread does a pthread_exit(0); so that the recieving thread can check for a return value of zero.
I thought i might try to use pthread_cond_timedwait() to achieve a similar effect, however I think i am missing a step.
I thought I would be able to make worker Thread A signal a condition AND pthread_exit() within a mutex, , and worker Thread B could wake up on the signal, and then pthread_join(). The problem is, Thread B doesn't know which thread threw the conditional signal. Do I need to explicitly pass that as part of the conditonal signal or what?
Thanks
Derek
Here is a portable implementation of pthread_timedjoin_np. It's a bit costly, but it's a full drop-in replacement:
struct args {
int joined;
pthread_t td;
pthread_mutex_t mtx;
pthread_cond_t cond;
void **res;
};
static void *waiter(void *ap)
{
struct args *args = ap;
pthread_join(args->td, args->res);
pthread_mutex_lock(&args->mtx);
args->joined = 1;
pthread_mutex_unlock(&args->mtx);
pthread_cond_signal(&args->cond);
return 0;
}
int pthread_timedjoin_np(pthread_t td, void **res, struct timespec *ts)
{
pthread_t tmp;
int ret;
struct args args = { .td = td, .res = res };
pthread_mutex_init(&args.mtx, 0);
pthread_cond_init(&args.cond, 0);
pthread_mutex_lock(&args.mtx);
ret = pthread_create(&tmp, 0, waiter, &args);
if (!ret)
do ret = pthread_cond_timedwait(&args.cond, &args.mtx, ts);
while (!args.joined && ret != ETIMEDOUT);
pthread_mutex_unlock(&args.mtx);
pthread_cancel(tmp);
pthread_join(tmp, 0);
pthread_cond_destroy(&args.cond);
pthread_mutex_destroy(&args.mtx);
return args.joined ? 0 : ret;
}
There may be small errors since I wrote this on the spot and did not test it, but the concept is sound.
Producer-consumer queue. Have the threads queue *themselves, and so their results,(if any), to the queue before they exit. Wait on the queue.
No polling, no latency.
With your current design, you would have to join() the returned threads get the valueptr and to ensure that they are destroyed.
Maybe you could sometime move to a real threadpool, where task items are queued to threads that never terminate, (so eliminating thread create/terminate/destroy overhead)?
solution with alarm.
pthread should enable cancel, so it can stop by external.(even with pthread_timedjoin_np).
pthread_timedjoin_np return with ETIMEOUT after waited time.
set alarm, use alarm also can give "TIMEOUT" signal.
In handler, just pthread_cancel it. (only timeout run this).
pthread_join it in main thread.
reset alarm
I write test code in here:github
I'm having a little trouble with pthreads. Basically, I want to catch a SIGINT and have all threads cleanup and exit. What I have (skeleton code):
main.c:
sig_atomic_t running;
void handler(int signal_number)
{
running = 0;
}
int main(void)
{
queue job_queue = new_job_queue();
running = 1;
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = &handler;
sigaction(SIGINT, &sa, NULL);
/* create a bunch of threads */
init_threads(&job_queue);
while(running) {
/* do stuff */
}
cleanup();
return (0);
}
threads.c
extern sig_atomic_t running;
pthread_mutex_t queue_mutex = PTHREAD_MUTEX_INITIALIZER;
sem_t queue_count;
void init_threads(queue *q)
{
int numthreads = 12; /* say */
sem_init (&queue_count, 0, 0);
pthread_t worker_threads[numthreads];
int i;
for(i=0;i<numthreads;i++)
pthread_create(&worker_threads[i], NULL, &thread_function, q);
}
void * thread_function(void *args)
{
pthread_detatch(pthread_self());
queue *q = (queue *)args;
while(running) {
job *j = NULL;
sem_wait(&queue_count);
pthread_mutex_lock(&queue_mutex);
j = first_job_in_queue(q);
pthread_mutex_unlock(&queue_mutex);
if(j) {
/*do something*/
}
}
return (NULL);
}
I am having little luck with this. Since you're not guarenteed which thread gets the signal I thought this was a good way to go. But I am having a problem where sem_wait() in threads.c is hanging, which is expected but not desired. The while(running) loop in threads.c seems redundant. Should I maybe do a pthread_kill() to all the threads from main? Any obvious problems with the above skeleton code? Is there a better/easier way to go about doing this?
Thanks.
What you can do is to call sem_post() from the handler until all threads are unlocked. In the thread function, immediately after sem_wait() you should check the value of the running variable and if it's zero break breom the while.
The code in the handler could be something like the following:
int sval;
sem_getvalue(&queue_count, &sval);
while (sval < 0) {
sem_post(&queue_count);
sem_getvalue(&queue_count, &sval);
}
Of course return values should be verified for errors
You can catch SIGINT in one thread, and use pthread_sigmask() to block SIGINT in all other threads, if SIGINT generated by some way, the signal will be delivered to the specified thread, that thread can call pthread_cancel() to cancel all other threads.
You may want to consider calling pthread_join after each call to pthread_create. This will allow for your main thread to wait until all threads are done executing.
But maybe I'm misunderstanding slightly... Do you want to wait for all threads to finish, or simply wait for one to finish, and then stop all others immediately?
You shouldn't do a pthread_kill() if you don't have to. I'm not to familiar with pthread_detatch() but if you are wanting your main() function to wait for the threads to finish, it would probably be better if your cleanup() function did a pthread_join() on each thread id returned from pthread_create() to wait for each thread to exit normally.
Also, as far as I can tell, sem_wait() is hanging because your semaphore value is initialized to 0. If you want say at most 5 threads to access the shared resource at a time, initialize the semaphore to 5, i.e. sem_init(&queue_count, 0, 5).
I am migrating an applciation from windows to linux. I am facing problem with respect to WaitForSingleObject and WaitForMultipleObjects interfaces.
In my application I spawn multiple threads where all threads wait for events from parent process or periodically run for every t seconds.
I have checked pthread_cond_timedwait, but we have to specify absolute time for this.
How can I implement this in Unix?
Stick to pthread_cond_timedwait and use clock_gettime. For example:
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
ts.tv_sec += 10; // ten seconds
while (!some_condition && ret == 0)
ret = pthread_cond_timedwait(&cond, &mutex, &ts);
Wrap it in a function if you wish.
UPDATE: complementing the answer based on our comments.
POSIX doesn't have a single API to wait for "all types" of events/objects as Windows does. Each one has its own functions. The simplest way to notify a thread for termination is using atomic variables/operations. For example:
Main thread:
// Declare it globally (argh!) or pass by argument when the thread is created
atomic_t must_terminate = ATOMIC_INIT(0);
// "Signal" termination by changing the initial value
atomic_inc(&must_terminate);
Secondary thread:
// While it holds the default value
while (atomic_read(&must_terminate) == 0) {
// Keep it running...
}
// Do proper cleanup, if needed
// Call pthread_exit() providing the exit status
Another alternative is to send a cancellation request using pthread_cancel. The thread being cancelled must have called pthread_cleanup_push to register any necessary cleanup handler. These handlers are invoked in the reverse order they were registered. Never call pthread_exit from a cleanup handler, because it's undefined behaviour. The exit status of a cancelled thread is PTHREAD_CANCELED. If you opt for this alternative, I recommend you to read mainly about cancellation points and types.
And last but not least, calling pthread_join will make the current thread block until the thread passed by argument terminates. As bonus, you'll get the thread's exit status.
For what it's worth, we (NeoSmart Technologies) have just released an open source (MIT licensed) library called pevents which implements WIN32 manual and auto-reset events on POSIX, and includes both WaitForSingleObject and WaitForMultipleObjects clones.
Although I'd personally advise you to use POSIX multithreading and signaling paradigms when coding on POSIX machines, pevents gives you another choice if you need it.
I realise this is an old question now, but for anyone else who stumbles across it, this source suggests that pthread_join() does effectively the same thing as WaitForSingleObject():
http://www.ibm.com/developerworks/linux/library/l-ipc2lin1/index.html
Good luck!
For WaitForMultipleObjects with false WaitAll try this:
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
using namespace std;
pthread_cond_t condition;
pthread_mutex_t signalMutex;
pthread_mutex_t eventMutex;
int finishedTask = -1;
void* task(void *data)
{
int num = *(int*)data;
// Do some
sleep(9-num);
// Task finished
pthread_mutex_lock(&eventMutex); // lock until the event will be processed by main thread
pthread_mutex_lock(&signalMutex); // lock condition mutex
finishedTask = num; // memorize task number
pthread_cond_signal(&condition);
pthread_mutex_unlock(&signalMutex); // unlock condtion mutex
}
int main(int argc, char *argv[])
{
pthread_t thread[10];
pthread_cond_init(&condition, NULL);
pthread_mutex_init(&signalMutex, NULL); // First mutex locks signal
pthread_mutex_init(&eventMutex, NULL); // Second mutex locks event processing
int numbers[10];
for (int i = 0; i < 10; i++) {
numbers[i] = i;
printf("created %d\n", i); // Creating 10 asynchronous tasks
pthread_create(&thread[i], NULL, task, &numbers[i]);
}
for (int i = 0; i < 10;)
{
if (finishedTask >= 0) {
printf("Task %d finished\n", finishedTask); // handle event
finishedTask = -1; // reset event variable
i++;
pthread_mutex_unlock(&eventMutex); // unlock event mutex after handling
} else {
pthread_cond_wait(&condition, &signalMutex); // waiting for event
}
}
return 0;
}