我想使用 setjmp()/ longjmp()来实现一个协程系统.然后我决定编写一个.c文件来测试它.在MinGW,没关系; 我得到了我想要的结果.但是当我在MSVC++中编译它时,程序崩溃:"访问冲突"
#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>
jmp_buf a;
int is_invoke=0;
void
action_1()
{
for ( ;; ) {
printf("hello~~~A\n");
if(!setjmp(a)) {
is_invoke=1;
return;
}
}
}
void
func()
{
if (is_invoke) {
longjmp(a,1);
}
action_1();
printf("end\n");
}
void
dummy()
{
;
}
int
main(int argc, char *argv[])
{
for ( ;; ) {
func();
dummy();
}
return 0;
}
Run Code Online (Sandbox Code Playgroud) 嗨,我需要从一个地方跳到另一个地方......
但我想知道哪个更好用,setjmp或ucontext,比如:
请提供我要求的更多信息,例如示例或一些文档......
我在网上搜索过,但是我只在C语言中得到异常处理,就像setjmp的例子一样,我对ucontex.h一无所知,我得知它用于多任务,它和pthread的区别是什么?
非常感谢.
我想使用 setjmp/longjmp 在主函数中重用一些代码(注意:这只是一个练习,而不是我在现实世界中认真计划做的事情)。以下代码是我想出的:
#include <stdio.h>
#include <setjmp.h>
jmp_buf jmp_body, jmp_ret;
void func(void)
{
if (setjmp(jmp_ret) == 0)
longjmp(jmp_body, 1);
}
int main()
{
int x = 0;
if (setjmp(jmp_body) == 1) {
printf("Body %d\n", ++x);
longjmp(jmp_ret, 1);
}
func();
func();
func();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我期望此代码的工作方式如下:
main()函数将记住“主体”部分的位置并使用if (setjmp(jmp_body) == 1).func()调用将暂时跳转到主体longjmp(jmp_body)usingif (setjmp(jmp_ret) == 0)func()调用使用longjmp(jmp_ret, 1)func()只是要恢复到main()正常。因此,我期望打印的代码如下:
Body 1
Body 2
Body 3
Run Code Online (Sandbox Code Playgroud)
相反,它永远循环不断地执行主体,这向我表明 …
标题说明了一切。之后包括<csetjmp>,longjmp和jmp_buf都在std命名空间中,但setjmp不是。我在 MinGW4.5 和 MSVC10 上验证了这一点。查看<csetjmp>标题后,我无法弄清楚这个选择的原因。我一直假设每个<cheader>文件都<header.h>在std命名空间中包装 a 。
我错了吗 ?setjmp特殊情况背后的基本原理是什么?请赐教!
注意:我知道在 C++ 中滥用 setjmp/longjmp 的问题。
要使setjmp/longjmp起作用,您需要将局部变量声明为volatile.如果有人用-O3编译其代码,那么volatile变量对性能的影响是多少.在x86多核平台上它会是巨大的还是只有一点点?
在我看来,它只会增加一点点开销,因为挥发性变量仍然可以缓存,无论如何从缓存读取/写入都非常快.意见?
在C参考手册,附录B介绍两种功能setjmp,并longjmp为一些所谓的非本地的跳跃.除了setjmp保存状态信息和longjmp恢复的基本理解之外state,我还无法理解此功能的确切流程和用例.
那么,这个功能到底完成了什么,它在哪里有用?
我正在将软件从嵌入式计算机移植到Linux机器上.(Ubuntu 14.04或Raspbian(raspberry pi))
原始程序使用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 …Run Code Online (Sandbox Code Playgroud) #include <csetjmp>
template <typename Callable>
void create_checkpoint(std::jmp_buf buf, Callable&& callable)
{
if (setjmp(buf) != 0)
{
callable();
}
}
#include <iostream>
struct announcer {
int id;
announcer(int id):
id{id}
{
std::cout << "created announcer with id " << id << '\n';
}
~announcer() {
std::cout << "destructing announcer with id " << id << '\n';
}
};
void oopsie(std::jmp_buf buf, bool shouldJump)
{
if (shouldJump)
{
// std::cout << "performing jump...\n";
std::longjmp(buf, 1);
}
}
void test1()
{
std::jmp_buf …Run Code Online (Sandbox Code Playgroud) 假设我有一些 C++ 代码,其中有一个 try-catch 块,其中该catch部分将触发长跳转:
#include <stdexcept>
#include <stdio.h>
#include <setjmp.h>
void my_fun()
{
jmp_buf jump_buffer;
if (setjmp(jump_buffer))
return;
try {
std::string message;
message.resize(100);
snprintf(&message[0], 100, "error code %d\n", 3);
throw std::runtime_error(message);
}
catch (std::runtime_error &e) {
longjmp(jump_buffer, 1);
}
}
Run Code Online (Sandbox Code Playgroud)
由于该std::runtime_error对象是在某处动态分配的,因此它是否会泄漏为其或字符串分配的内存?
据我了解,setjmp保存当前上下文,并且应该在调用时还原它longjmp。但是,下一段代码将显示15(我使用-g编译,没有进行任何优化)。我是不是误解了这种结构,还是想念其他东西?
#include <iostream>
#include <csetjmp>
std::jmp_buf jump_buffer;
int main()
{
int a = 0;
if (setjmp(jump_buffer) == 0) {
a = 15;
std::longjmp(jump_buffer, 42);
}
std::cerr << a << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
免责声明:仅出于好奇而尝试使用它。直到最近我阅读了一些有关NASA编码准则的论文,并提到禁止使用这种控制结构流程之后,我才听说过这种结构。
因为代码是混合的,所以同时使用c和c ++标记,并且我认为实际的相关功能与c重度用户更相关,而不是c ++ ...:/