Główna funkcja opiera się na libevent, ale w tej funkcji jest długotrwałe zadanie. Więc zacznij N kroków, aby uruchomić zadania. Czy ten pomysł jest OK? I jak korzystać z libevent i pthread razem w C?Jak korzystać z libevent i pthread razem w C
Odpowiedz
To by działało.
W funkcji wywołania zwrotnego we/wy deleguje czasochłonne zadanie do innego wątku puli wątków. Dokładna mechanika zależy od interfejsu wątku roboczego lub puli wątków.
Aby przekazać wynik z powrotem z wątku roboczego do wątku I/O, użyj potoku. Wątek roboczy zapisuje wskaźnik do obiektu wynikowego na rurze, a wątek I/O budzi się i odczytuje wskaźnik z rury.
Jest to wielowątkowy libevent przykładem w tym blogu: http://www.roncemer.com/multi-threaded-libevent-server-example
Jego rozwiązaniem jest, aby zacytować:
Rozwiązaniem jest stworzenie jednej kolejki zdarzeń libevent (AKA event_base) na aktywnym połączeniu , każdy z własnym gwintem pompy zdarzenia. Ten projekt ma dokładnie to, co daje ci wszystko, czego potrzeba do tworzenia wysokowydajnych, wielowątkowych, opartych na libevent serwerów gniazd.
Zepsuty link lub serwer jest wyłączony. Skopiuj i wklej kod oprócz adresów URL, a nie tylko linki. – enthusiasticgeek
@enthusiasticgeek, Serwer jest uruchomiony i jego blog na blogu nie zawiera postów dotyczących libevent, więc może znalazł błąd i właśnie usunął wpis. Oto migawka strony z 2012 roku: http://web.archive.org/web/20120707080222/http://www.roncemer.com/multi-threaded-libevent-server-example Tutaj jest projekt sourceforge połączony- na podstawie migawki: http://sourceforge.net/projects/libevent-thread/ Nie patrzyłem na to od jakiegoś czasu, ale możesz samodzielnie wyciąć i wkleić kod, jeśli masz już problem z głową . – ahcox
Dzięki za linki! – enthusiasticgeek
UWAGA To jest dla libev nie libevent, ale pomysł może mieć zastosowanie.
Tutaj przedstawiam przykład dla społeczności. Proszę skomentuj i daj mi znać, jeśli pojawią się jakieś zauważalne błędy. Ten przykład może zawierać procedurę obsługi sygnału dla zakończenia wątku i płynnego wyjścia w przyszłości.
//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;
}
Wpadnięcie na stare pytanie mogło już zostać rozwiązane. Ale zamieszczanie odpowiedzi na wypadek, gdyby ktoś jej potrzebował.
Tak, nic nie szkodzi powielaniu w tym przypadku. Ostatnio użyłem libevent w pthreads i wygląda na to, że działa dobrze. Oto kod:
#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 *ev;
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);
}
Jak widać, w moim przypadku wydarzenie dla głównego wątku to timer. Logika baza następnie jest jak poniżej:
- wezwanie evthread_use_pthreads() zainicjować biblioteki libevent dla pthreads na Linux (moim przypadku). Dla okien evthread_use_window_threads(). Sprawdź samą dokumentację podaną w event.h.
- Przydziel strukturę event_base na globalnej stercie zgodnie z instrukcją w dokumentacji. Upewnij się, że zwracasz wartość błędów.
- To samo co powyżej, ale przydzielać samą strukturę zdarzenie. W moim przypadku nie czekam na deskryptor pliku, więc -1 jest przekazywane jako argument. Ponadto chcę, aby moje wydarzenie się utrzymywało, stąd EV_PERSIST. Kod funkcji zwrotnych jest pominięty.
- Harmonogram imprezy dla realizacji
- Uruchom pętli zdarzeń
- wolnych zasobów po zakończeniu.
wersja libevent stosowany w moim przypadku jest libevent2 5.1.9, a także potrzebują libevent_pthreads.so bibliotekę do linkowania.
okrzyki.
- 1. Używanie pthread w języku C++
- 2. Wątki w C, C++, C++ 0x, Pthread i zwiększyć
- 3. Czy można razem korzystać z GET i POST?
- 4. autoconf z -pthread
- 5. Jak używać C++ i obiektywu-c razem w XCode 4.2
- 6. Jak działa pthread?
- 7. Jak zbudować libevent w wersji 2.0.10 z Visual Studio 2008
- 8. Mnożąc char i int razem w C
- 9. Używanie fscanf i fprintf razem w C
- 10. jak korzystać z odwrotnego C
- 11. Jak korzystać z qrc w aplikacjach C++ i QML?
- 12. Jak korzystać z GetProcessMemoryInfo w C++?
- 13. Jak korzystać z właściwości w języku C#?
- 14. Jak korzystać z flag bitowych w C++?
- 15. Jak korzystać z TransactionScope w języku C#?
- 16. Jak korzystać z timera w C?
- 17. Jak korzystać z funkcji klasy w C++?
- 18. Operatory gwiazdek i uchwytów C++ używane razem
- 19. Błąd: oczekiwano e ?! Jak korzystać z wtyczek i wtyczek zaćmień razem w sbt?
- 20. Jak korzystać z klas C++ z ctypes?
- 21. Jak korzystać z biblioteki C z D?
- 22. Dokumentacja Objective-C i Swift razem z dokumentacją Apple
- 23. OS X dzyń -pthread
- 24. Jak się przespać lub zatrzymać PThread in c na Linuksie
- 25. Jak korzystać z bind1st i bind2nd?
- 26. jak zakończyć wątek spania w pthread?
- 27. C# DataSet.Relations: Jak korzystać z powiązań DataSet?
- 28. Kompilowanie plików C i C++ razem przy użyciu GCC
- 29. kolejka blokowania synchronizowanego pthread
- 30. Cel C - Jak korzystać z zmiennych zewnętrznych?
Jest to dość łatwe do zrobienia z procesami, jeśli spojrzeć na przekazane przez OpenBSD, istnieje kod dla wielu procesów obsługujących przychodzące żądania. – tbert