Merge branch 'thread' of https://git.shs.tools/SHS/pip into thread

This commit is contained in:
Бычков Андрей
2022-11-10 14:08:57 +03:00
6 changed files with 64 additions and 10 deletions

View File

@@ -839,7 +839,7 @@ PIObject::Deleter::Deleter() {
PRIVATE->thread.setSlot([this](){ PRIVATE->thread.setSlot([this](){
PIVector<PIObject*> oq; PIVector<PIObject*> oq;
PRIVATE->thread.lock(); PRIVATE->thread.lock();
while(PRIVATE->obj_queue.isEmpty()) PRIVATE->cond_var.wait(PRIVATE->thread.mutex()); PRIVATE->cond_var.wait(PRIVATE->thread.mutex());
oq.swap(PRIVATE->obj_queue); oq.swap(PRIVATE->obj_queue);
PRIVATE->thread.unlock(); PRIVATE->thread.unlock();
for (PIObject * o : oq) deleteObject(o); for (PIObject * o : oq) deleteObject(o);
@@ -851,7 +851,9 @@ PIObject::Deleter::Deleter() {
PIObject::Deleter::~Deleter() { PIObject::Deleter::~Deleter() {
//piCout << "~Deleter ..."; //piCout << "~Deleter ...";
PRIVATE->thread.stop(); PRIVATE->thread.stop();
PRIVATE->thread.mutex().lock();
PRIVATE->cond_var.notifyAll(); PRIVATE->cond_var.notifyAll();
PRIVATE->thread.mutex().unlock();
PRIVATE->thread.waitForFinish(); PRIVATE->thread.waitForFinish();
for (PIObject * o : PRIVATE->obj_queue) deleteObject(o); for (PIObject * o : PRIVATE->obj_queue) deleteObject(o);
//piCout << "~Deleter ok"; //piCout << "~Deleter ok";

View File

@@ -95,6 +95,27 @@ bool PIWaitEvent::wait(int fd, CheckRole role) {
} }
bool PIWaitEvent::sleep(int us) {
if (!isCreate()) return false;
#ifdef WINDOWS
DWORD ret = WaitForSingleObjectEx(event, us / 1000, TRUE);
ResetEvent(event);
return ret == WAIT_TIMEOUT;
#else
int nfds = pipe_fd[ReadEnd] + 1;
FD_ZERO(&(fds[CheckRead]));
FD_SET(pipe_fd[ReadEnd], &(fds[CheckRead]));
timeval timeout;
timeout.tv_sec = us / 1000000;
timeout.tv_usec = us % 1000000;
int ret = ::select(nfds, &(fds[CheckRead]), nullptr, nullptr, &timeout);
int buf = 0;
while (::read(pipe_fd[ReadEnd], &buf, sizeof(buf)) > 0);
return ret == 0;
#endif
}
void PIWaitEvent::interrupt() { void PIWaitEvent::interrupt() {
if (!isCreate()) return; if (!isCreate()) return;
#ifdef WINDOWS #ifdef WINDOWS

View File

@@ -31,7 +31,7 @@
#endif #endif
class PIWaitEvent { class PIP_EXPORT PIWaitEvent {
public: public:
~PIWaitEvent(); ~PIWaitEvent();
@@ -44,6 +44,7 @@ public:
void create(); void create();
void destroy(); void destroy();
bool wait(int fd = -1, CheckRole role = CheckRead); bool wait(int fd = -1, CheckRole role = CheckRead);
bool sleep(int us); // return if sleep done
void interrupt(); void interrupt();
bool isCreate() const; bool isCreate() const;
void * getEvent() const; // WINDOWS only void * getEvent() const; // WINDOWS only

View File

@@ -485,7 +485,7 @@ void __PIThreadCollection::stoppedAuto() {
auto_mutex.lock(); auto_mutex.lock();
auto_threads_.removeAll(t); auto_threads_.removeAll(t);
auto_mutex.unlock(); auto_mutex.unlock();
delete t; t->deleteLater();
} }

View File

@@ -19,6 +19,7 @@
#include "pitimer.h" #include "pitimer.h"
#include "piincludes_p.h" #include "piincludes_p.h"
#include "piconditionvar.h"
#ifdef PIP_TIMER_RT #ifdef PIP_TIMER_RT
# include <csignal> # include <csignal>
#endif #endif
@@ -187,9 +188,11 @@ private:
virtual bool stopTimer(bool wait); virtual bool stopTimer(bool wait);
static void threadFuncS(void * d) {((_PITimerImp_Thread*)d)->threadFunc();} static void threadFuncS(void * d) {((_PITimerImp_Thread*)d)->threadFunc();}
void adjustTimes(); void adjustTimes();
bool smallWait(int ms);
PIThread thread_; PIThread thread_;
PISystemTime st_time, st_inc, st_wait, st_odt; PISystemTime st_time, st_inc, st_wait, st_odt;
PIConditionVariable event;
}; };
@@ -235,9 +238,9 @@ private:
_PITimerImp_Thread::_PITimerImp_Thread() { _PITimerImp_Thread::_PITimerImp_Thread() {
thread_.setName("__S__PITimerImp_Thread::thread"); thread_.setName("__S__PITimerImp_Thread::thread");
wait_dt = 100; wait_dt = 1000;
wait_dd = 200; wait_dd = 2000;
wait_tick = 10; wait_tick = 1000;
//piCout << "_PITimerImp_Thread" << this << ", thread& =" << &thread_; //piCout << "_PITimerImp_Thread" << this << ", thread& =" << &thread_;
//piCout << "new _PITimerImp_Thread"; //piCout << "new _PITimerImp_Thread";
} }
@@ -275,6 +278,9 @@ bool _PITimerImp_Thread::startTimer(double interval_ms) {
bool _PITimerImp_Thread::stopTimer(bool wait) { bool _PITimerImp_Thread::stopTimer(bool wait) {
thread_.stop(); thread_.stop();
thread_.mutex().lock();
event.notifyAll();
thread_.mutex().unlock();
if (wait) return thread_.waitForFinish(); if (wait) return thread_.waitForFinish();
// if (wait) // if (wait)
// if (!thread_.waitForFinish(10)) // if (!thread_.waitForFinish(10))
@@ -296,10 +302,10 @@ bool _PITimerImp_Thread::threadFunc() {
dwt = st_time - PISystemTime::current(true); dwt = st_time - PISystemTime::current(true);
if (wth > 0) { if (wth > 0) {
if (dwt.toMilliseconds() > wth + 1.) { if (dwt.toMilliseconds() > wth + 1.) {
piMSleep(wth); smallWait(wth);
return false; return false;
} else { } else {
dwt.sleep(); if (!smallWait(dwt.toMilliseconds())) return false;
deferred_ = false; deferred_ = false;
st_time = PISystemTime::current(true); st_time = PISystemTime::current(true);
} }
@@ -318,11 +324,11 @@ bool _PITimerImp_Thread::threadFunc() {
} }
if (wait_tick > 0) { if (wait_tick > 0) {
if (st_wait.toMilliseconds() > wait_tick + 1.) { if (st_wait.toMilliseconds() > wait_tick + 1.) {
piMSleep(wait_tick); smallWait(wait_tick);
return false; return false;
} else { } else {
//piCout << &thread_ << "sleep for" << st_wait; //piCout << &thread_ << "sleep for" << st_wait;
st_wait.sleep(); if (!smallWait(st_wait.toMilliseconds())) return false;
} }
} else { } else {
if (st_wait.toMilliseconds() > 0.1) if (st_wait.toMilliseconds() > 0.1)
@@ -363,6 +369,14 @@ void _PITimerImp_Thread::adjustTimes() {
} }
bool _PITimerImp_Thread::smallWait(int ms) {
thread_.mutex().lock();
event.waitFor(thread_.mutex(), ms);
thread_.mutex().unlock();
return !thread_.isStopping();
}
#ifdef PIP_TIMER_RT #ifdef PIP_TIMER_RT

View File

@@ -3,6 +3,7 @@
#include "pibytearray.h" #include "pibytearray.h"
#include "pimathbase.h" #include "pimathbase.h"
#include "pijson.h" #include "pijson.h"
#include "piwaitevent_p.h"
using namespace PICoutManipulators; using namespace PICoutManipulators;
@@ -88,6 +89,21 @@ void phase(const char * msg) {
int main(int argc, char * argv[]) { int main(int argc, char * argv[]) {
piCout << "main"; piCout << "main";
PITimer timer;
timer.setSlot([](){
static int cnt = 0;
piCout << "tick" << ++cnt;
});
timer.start(500);
piSleep(1.12);
piCout << "end";
PITimeMeasurer tm;
timer.stop();
double tm_ms = tm.elapsed_m();
piCout << "stop took" << tm_ms;
return 0;
/*for (int i = 0; i < count; ++i) /*for (int i = 0; i < count; ++i)
pipes[i].create(); pipes[i].create();