阻塞线程直到系统时钟发生第二次变化
Block thread until second changes on system clock
我正在编写一个程序,根据我的系统时钟每秒发送脉冲输出。尽可能准确是很重要的。
我正在使用 XCode 作为我的调试器,然后我在另一个系统上独立 运行 这个。
我正在使用一个分离的 pthread
,它通过一个(不是我写的)函数发送输出。
我知道 sleep(int seconds)
调用,但是这不是时钟同步的,我不太确定准确性...
我四处寻找更好的解决方案,但只遇到了 C 的 time.h
tm
结构。有没有办法阻止我的线程直到 tm
更改的第二个,或者任何其他更好的解决方案?
这里是我的线程函数,供参考。
/*One PPS*/
void *_THD_One_PPS(void *args) {
/* Description: Send a 1 millisecond pulse every second */
selfargs_t *self = args;
pthread_detach(pthread_self());
double dutyCycle = 0.001;
long unsigned onTime = dutyCycle * 1000000000; // Time signal high, ns
while (self->myself->ThreadActiveStatus != THD_DONE) {
sleep(1); //TODO: Sync with clock as much as possible
printf("/\ ");
setPinValue(BBB_GPIO_PIN_ONE_PPS, ON);
pauseNanoSec(onTime);
setPinValue(BBB_GPIO_PIN_ONE_PPS, OFF);
}
printf("Pulse Per Sec DIED");
_T_ThreadsDied++;
_T_ThreadsAlive--;
self->myself->ThreadActiveStatus = THD_DONE;
free(self->arguments);
free(self);
return NULL;
}
有没有更简单或更好的方法来做到这一点?
您可以使用 clock_nanosleep()
的睡眠到绝对时间功能来执行此操作:
const double dutyCycle = 0.001;
struct timespec deadline;
clock_gettime(CLOCK_MONOTONIC, &deadline);
while (self->myself->ThreadActiveStatus != THD_DONE) {
/* Sleep until start of next second tick */
deadline.tv_sec += 1;
deadline.tv_nsec = 0;
while (clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &deadline, NULL) != 0)
if (errno != EINTR) return NULL;
setPinValue(BBB_GPIO_PIN_ONE_PPS, ON);
/* Sleep until duty cycle expired */
deadline.tv_nsec = dutyCycle * 1000000000;
while (clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &deadline, NULL) != 0)
if (errno != EINTR) return NULL;
setPinValue(BBB_GPIO_PIN_ONE_PPS, OFF);
}
我正在编写一个程序,根据我的系统时钟每秒发送脉冲输出。尽可能准确是很重要的。
我正在使用 XCode 作为我的调试器,然后我在另一个系统上独立 运行 这个。
我正在使用一个分离的 pthread
,它通过一个(不是我写的)函数发送输出。
我知道 sleep(int seconds)
调用,但是这不是时钟同步的,我不太确定准确性...
我四处寻找更好的解决方案,但只遇到了 C 的 time.h
tm
结构。有没有办法阻止我的线程直到 tm
更改的第二个,或者任何其他更好的解决方案?
这里是我的线程函数,供参考。
/*One PPS*/
void *_THD_One_PPS(void *args) {
/* Description: Send a 1 millisecond pulse every second */
selfargs_t *self = args;
pthread_detach(pthread_self());
double dutyCycle = 0.001;
long unsigned onTime = dutyCycle * 1000000000; // Time signal high, ns
while (self->myself->ThreadActiveStatus != THD_DONE) {
sleep(1); //TODO: Sync with clock as much as possible
printf("/\ ");
setPinValue(BBB_GPIO_PIN_ONE_PPS, ON);
pauseNanoSec(onTime);
setPinValue(BBB_GPIO_PIN_ONE_PPS, OFF);
}
printf("Pulse Per Sec DIED");
_T_ThreadsDied++;
_T_ThreadsAlive--;
self->myself->ThreadActiveStatus = THD_DONE;
free(self->arguments);
free(self);
return NULL;
}
有没有更简单或更好的方法来做到这一点?
您可以使用 clock_nanosleep()
的睡眠到绝对时间功能来执行此操作:
const double dutyCycle = 0.001;
struct timespec deadline;
clock_gettime(CLOCK_MONOTONIC, &deadline);
while (self->myself->ThreadActiveStatus != THD_DONE) {
/* Sleep until start of next second tick */
deadline.tv_sec += 1;
deadline.tv_nsec = 0;
while (clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &deadline, NULL) != 0)
if (errno != EINTR) return NULL;
setPinValue(BBB_GPIO_PIN_ONE_PPS, ON);
/* Sleep until duty cycle expired */
deadline.tv_nsec = dutyCycle * 1000000000;
while (clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &deadline, NULL) != 0)
if (errno != EINTR) return NULL;
setPinValue(BBB_GPIO_PIN_ONE_PPS, OFF);
}