【发布时间】:2016-11-09 03:03:12
【问题描述】:
我正在将软件从嵌入式计算机移植到 Linux 计算机。 (Ubuntu 14.04 或 Raspbian(树莓派))
原始程序使用 setjmp/longjmp 来处理超时和 CTRL+C 事件。它在具有单个主线程(一个线程)的微控制器上运行。
我试图在使用线程 (pthreads) 时有类似的行为。
我的想法是我想要超时或 CTRL+C 来重新启动无限循环。
原始代码的作用类似于下面的代码。我不介意用其他东西删除 setjmp/longjmp。 (例如:try/catch 或 signal 或 pthread_kill、条件变量等)
知道如何用 C/C++ 实现类似的行为吗?
这是似乎部分工作的代码,可能不推荐/损坏:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <setjmp.h>
// Define
#define TICK_NS_TIME (10000000) // 0.01 sec = 10 ms (100 times per second)
#define NS_PER_SEC (1000000000) // Nano sec per second.
#define TICK_PER_SEC (NS_PER_SEC/TICK_NS_TIME) // Number of tick per second (Ex:100)
#define TIMEOUT_COUNT (30*TICK_PER_SEC) // 30 seconds timeout (with 100 tick per second)
// Env set/long jmp
#define ENV_SZ (2)
#define ENV_TIMEOUT (0)
#define ENV_CTRLC (1)
static jmp_buf env[ENV_SZ];
// Variables
int timeout_val;
// sig handler.
void signal_handler(int signo)
{
pthread_t self = pthread_self();
printf("Thread %lu in signal handler\n", (long)self);
if (signo == SIGINT) {
longjmp(env[ENV_CTRLC], 1); // Q?: Is it in the same thread ? (Never, Always, Sometimes?)
}
else
{
printf("Other signal received..quitting."); // Ex: kill -9 pid
exit(0);
}
}
// thread timer function
void* timer_function(void* in_param)
{
// Loop approx 100x per second.
for (;;) {
nanosleep((const struct timespec[]){{0, TICK_NS_TIME }}, NULL); // Sleep 10 ms seconds.
if (timeout_val) {
if (!--timeout_val) {
longjmp(env[ENV_TIMEOUT], 1); // longjmp when timer reaches 0. (Q?: Is this valid with multithread?)
}
}
}
}
// main
int main(int argc, char **argv)
{
int i;
int val;
struct sigaction actions;
pthread_t thread;
setvbuf (stdout, NULL, _IONBF, 0); // Make sure stdout is not buffered (ex:printf, etc.)
printf("[Program started]\r\n");
memset(&actions, 0, sizeof(actions));
sigemptyset(&actions.sa_mask);
actions.sa_flags = 0;
actions.sa_handler = signal_handler;
val = sigaction(SIGINT, &actions, NULL);
pthread_create(&thread, NULL, timer_function, NULL); // timer thread for example
printf("[Timer thread started]\r\n");
// setting env.
val = setjmp(env[ENV_TIMEOUT]);
if (val!=0){ printf("[JMP TIMEOUT]\r\n"); }
val = setjmp(env[ENV_CTRLC]);
if (val!=0){ printf("[JMP CTRLC]\r\n"); }
// main loop
timeout_val = TIMEOUT_COUNT;
i = 0;
for (;;)
{
i++;
if (i > 10){ i = 0; printf("[%d]", timeout_val/TICK_PER_SEC); } // Number of seconds before time out.
sleep(1);
printf(".");
}
printf("Main completed\n");
return 0;
}
//Compile: g++ -pthread main.cpp -o main
由于我是使用线程编程的新手!
【问题讨论】:
-
没有语言 C/C++。只有不同的语言 C 和 C++。 C(您标记的)没有例外。关于问题:这不是咨询服务。你的问题太笼统了。令人困惑的是,嵌入式MCU通常没有标准库,也没有键盘,所以没有
ctrl-C。使用setjmp处理超时对我来说似乎是一个糟糕的设计。 -
原始代码是 C 语言并使用 setjmp/longjmp。它位于包含 CodeWarrior C 标准库的 Freescale MCU(16 位)上。 CTRLC 来自 UART。我想要类似的行为,但在 C++ 中使用线程。 (希望删除 setjmp)。
标签: c multithreading pthreads setjmp