- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
运行时间:
mehoggan@mehoggan-laptop:~/Code/svn_playground/C++/timer/timer0$ uname -a
Linux mehoggan-laptop 2.6.32-37-generic #81-Ubuntu SMP Fri Dec 2 20:32:42 UTC 2011 x86_64 GNU/Linux
mehoggan@mehoggan-laptop:~/Code/svn_playground/C++/timer/timer0$ cat /etc/*release*
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=10.04
DISTRIB_CODENAME=lucid
DISTRIB_DESCRIPTION="Ubuntu 10.04.3 LTS"
mehoggan@mehoggan-laptop:~/Code/svn_playground/C++/timer/timer0$ g++ --version
g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3
Copyright (C) 2009 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
mehoggan@mehoggan-laptop:~/Code/svn_playground/C++/timer/timer0$
我正在尝试编写一个在后台线程上运行并使用 gettimeofday(3) 函数和用户指定回调函数的计时器类。这将在我正在从 Windows 移植到 Linux 的 OpenGL 应用程序中使用。
当我运行这段代码时(见下文)。在 Release模式下运行时,我的线程挂起。但是,当我使用调试器逐步执行代码时,一切似乎都运行良好。这对我来说是一个时间问题。我对此可能是错误的,因为我刚刚学习如何使用线程。有人可以帮助我理解为什么我的线程应用程序从操作系统获取此信号吗?
有两个地方可以得到代码,你可以从我的trac网站下载: Trac Site
主要.CPP
#include "TimerManager.h"
#include <iostream>
#include <fstream>
#include <sys/time.h>
std::ofstream out;
void func1(int id)
{
struct timeval l_tv;
gettimeofday(&l_tv, NULL);
std::cout << "I was called (1) @ " << l_tv.tv_usec << std::endl;
out.flush();
}
void func2(int id)
{
struct timeval l_tv;
gettimeofday(&l_tv, NULL);
std::cout << "I was called (2) @ " << l_tv.tv_usec << std::endl;
out.flush();
}
int main(int, char *[])
{
out.open("/home/mehoggan/Desktop/log.log");
TimerManager t;
t.addTimer(1000000 * 10, func1);
t.addTimer(1000000 * 20, func2);
t.start();
while(true) {
sleep(1);
}
return 0;
}
#ifndef TIMERMANAGER_H_
#define TIMERMANAGER_H_
#include <stdlib.h>
#include <iostream>
#include <pthread.h>
#include <list>
extern "C" {
void *create_pthread(void *data);
}
class TimerManager {
public:
TimerManager();
~TimerManager();
void start();
void stop();
void addTimer(long usec, void (*callback)(int id));
private:
class Timer
{
public:
Timer(long usec, void (*callback)(int)) :
duration(usec),
callback(callback),
start(0)
{
}
bool operator ==(Timer other)
{
if ((this->callback == other.callback) && (this->duration == other.duration)) {
return true;
}
return false;
}
void operator =(Timer other)
{
duration = other.duration;
callback = other.callback;
start = other.start;
}
suseconds_t duration;
void (*callback)(int);
suseconds_t start;
};
std::list<Timer> m_timers;
Timer setUpTimer(long micro_duration, void (*callback)(int id));
friend void *create_pthread(void *data);
void run();
bool m_bRunning;
bool m_bGo;
long m_lMinSleep;
pthread_t m_tTimerThread;
pthread_cond_t m_tGoLockCondition;
pthread_mutex_t m_tGoLock;
};
#endif
#include <algorithm>
#include <iterator>
#include <sys/time.h>
#include "TimerManager.h"
extern "C" void *create_pthread(void *data)
{
TimerManager *thread_timer_manager = static_cast<TimerManager *>(data);
thread_timer_manager->run();
return data;
}
TimerManager::TimerManager() :
m_bRunning(false),
m_bGo(false),
m_lMinSleep(0)
{
int mutex_creation = pthread_mutex_init(&m_tGoLock, NULL);
if(mutex_creation != 0) {
std::cerr << "Failed to create mutex" << std::endl;
return;
}
int mutex_cond_creation = pthread_cond_init(&m_tGoLockCondition, NULL);
if(mutex_cond_creation != 0) {
std::cerr << "Failed to create condition mutex" << std::endl;
return;
}
int thread_creation = pthread_create(&m_tTimerThread, NULL, create_pthread, this);
if(thread_creation != 0) {
std::cerr << "Failed to create thread" << std::endl;
return;
}
m_bRunning = true;
}
TimerManager::~TimerManager()
{
m_bRunning = false;
pthread_mutex_destroy(&m_tGoLock);
void *result;
pthread_join(m_tTimerThread, &result);
}
void TimerManager::run()
{
pthread_mutex_lock(&m_tGoLock);
while(m_bRunning) {
while (!m_bGo) {
pthread_cond_wait(&m_tGoLockCondition, &m_tGoLock);
}
pthread_mutex_unlock(&m_tGoLock);
if (!m_bRunning) {
break;
}
pthread_detach(m_tTimerThread);
struct timeval l_tv;
sleep(std::max(0l, m_lMinSleep));
gettimeofday(&l_tv, NULL);
m_lMinSleep = 0;
long l_lMin = 0;
for(std::list<Timer>::iterator it = m_timers.begin(); it != m_timers.end(); ++it) {
TimerManager::Timer l_oTimer = *it;
long elapsed_time = ((l_tv.tv_sec * 1000000 + l_tv.tv_usec) - (l_oTimer.start));
l_lMin = elapsed_time - l_oTimer.duration;
if (elapsed_time >= l_oTimer.duration) {
l_lMin = l_oTimer.duration;
l_oTimer.callback(0);
gettimeofday(&l_tv, NULL);
it->start = (l_tv.tv_sec * 1000000) + l_tv.tv_usec;
}
m_lMinSleep = std::min(m_lMinSleep, l_lMin);
}
}
}
void TimerManager::start()
{
pthread_mutex_lock(&m_tGoLock);
m_bGo = true;
pthread_cond_signal(&m_tGoLockCondition);
pthread_mutex_unlock(&m_tGoLock);
}
void TimerManager::stop()
{
pthread_mutex_lock(&m_tGoLock);
m_bGo = false;
pthread_mutex_unlock(&m_tGoLock);
}
TimerManager::Timer TimerManager::setUpTimer(long micro_duration, void (*callback)(int id))
{
struct timeval l_tv;
gettimeofday(&l_tv, NULL);
Timer l_oTimer(micro_duration, callback);
l_oTimer.start = (l_tv.tv_sec * 1000000) + l_tv.tv_usec;
return l_oTimer;
}
void TimerManager::addTimer(long usec, void (*callback)(int id))
{
Timer insert = setUpTimer(usec, callback);
typedef std::list<Timer>::iterator li;
m_timers.push_back(insert);
}
最佳答案
好吧,你的析构函数肯定坏了。当另一个线程可能正在使用它时,您不能销毁它。当另一个线程可能正在访问它时,您不能修改 m_bRunning
。你想要:
TimerManager::~TimerManager()
{
pthread_mutex_lock(&m_tGoLock);
m_bRunning = false;
pthread_mutex_unlock(&m_tGoLock);
void *result;
pthread_join(m_tTimerThread, &result);
pthread_mutex_destroy(&m_tGoLock);
}
你有很多并发错误。例如,您的 addTimer
函数修改共享的 m_timers
结构而不持有互斥体。
关于c++ - pthreads SIGHUP on Simple Linux Timer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9147027/
我正在使用计时器以相当长的间隔(2分钟)定期运行事件。一切正常。但是,我希望在创建计时器时立即触发该事件(而不是等待2分钟)。 请注意,我不能仅通过调用方法来执行此操作,因为它需要一些时间才能运行,并
我正在检查一些可怕的遗留代码,这些代码具有 Timer 事件以及一些包含 DoEvents 调用的冗长代码。简化版如下所示: Private Sub tmrProcess_Timer()
我正在尝试创建一个 Windows 窗体应用程序,我想实现一个计时器。 public void timerStart() { DateTime now = DateTime
我正在创建一个新类,以便使 System.Timers.Timer 类更好地满足我的需要。我像这样创建我的新类...... using System.Timers; class BtElapsedEv
我最近一直在检查一些可能的计时器,并且 System.Threading.Timer和 System.Timers.Timer对我来说是必要的(因为它们支持线程池)。 我正在制作一款游戏,我计划使用所
首先我要说的是,与其说这是一个需要解决的问题,不如说这是一个问题。我现在有了解决方案,对我来说一切正常。但是我想知道为什么第一次出现问题。 这是我现在拥有的代码,它的工作方式与我预期的一样:
在本文中:http://msdn.microsoft.com/en-us/magazine/cc164015.aspx作者声明 System.Threading.Timer 不是线程安全的。 从那时起
背景: 我有一个计时器,我用它来跟踪自 serialPort DataReceived 事件被触发以来已经过了多长时间。我正在为此创建自己的解决方案而不是使用内置的超时事件,因为我正在获取连续的数据流
我正在查看 Flutter Timer代码和 cancel() 方法。当我想删除一个计时器时,我可以使用这两行: timer.cancel(); timer = null; 或者我可以这样做: 定时器
我正在尝试使用 C# 中的计时器以五秒的间隔运行一个方法。虽然这段代码似乎不起作用。运行它时我没有收到任何错误,但程序(我在控制台中运行)在 IP.timer1.Start() 之后立即关闭。 tim
我正在尝试使用 C# 中的计时器以五秒的间隔运行一个方法。虽然这段代码似乎不起作用。运行它时我没有收到任何错误,但程序(我在控制台中运行)在 IP.timer1.Start() 之后立即关闭。 tim
我有错误显示: 'Timer' is an ambiguous reference between 'System.Windows.Forms.Timer' and 'System.Threading
在我的应用程序中,我必须定期向“兄弟”应用程序发送心跳。 使用 System.Timers.Timer/Threading.Timer 或使用带有 while 循环和 Thread.Sleep 的线程
我最近遇到了编写 Windows 服务的挑战。我需要定期请求一个 URL 并检查它的可用性。为此,我决定在 OnStart 中初始化一个计时器。服务方法并在 timer_Tick 中完成所有工作事件。
看来 System.Timers.Timer 实例通过某种机制保持事件状态,但 System.Threading.Timer 实例则不然。 示例程序,具有定期System.Threading.Time
我做了一个 goog.Timer对象 ( http://closure-library.googlecode.com/svn/docs/class_goog_Timer.html ) 与 new go
当您处理“原始”.net 计时器时,您可以传入等待句柄以在 Win32 计时器被销毁后调用,并且您可以假设您的回调不会被调用。 (并且计时器将被 GC 视为“死”) 如何使用 System.Timer
我想让 deoplete 自动完成建议弹出得更快,这需要设置 g:deoplete#auto_complete_delay help 说这需要 +timers 支持。如何在配置中启用此计时器? 谢谢!
我想知道是否有合理的方法来确定 Timers.Timer 对象的负载能力?或者,更确切地说,线程功能。有人知道使用 Timer 类启动大量(数百个)线程是否有任何问题? 编辑:为了工作,我们将启动一些
我正在创建一个 WindowsService,它的 Timer 绑定(bind)到具有无限循环的 EventHandler;我希望能够在服务的 OnStart() 方法中触发此计时器一次,然后在服务的
我是一名优秀的程序员,十分优秀!