longjmp和多线程

看到有人用setjmp()/longjmp() 做的多线程例子。这种方法极容易造成堆栈冲突。非常不赞成这么用。如果用多线程,linux当然用pthread线程库。windows当然用CreateThread()。

原例子这里就不展示了。感兴趣可以自己搜索“setjmp 协程”。这里做了大幅修改,把原来的“主控(即主线程)和子线程”改为“主控(即调度程序)和两个子线程”。3个线程合作运行。但仍然有堆栈冲突的危险。最好每个线程有独立的运行栈,那样就又回到OS自己的多线程上来了。

这里分享上来,只为了爱好者扩大知识面,并不代表就可以实用了。调试,评估,然后扔掉:

#include <stdio.h>
#include <string.h>
#include <setjmp.h>
#include <stdlib.h>typedef int BOOL;
#define TRUE    1
#define FALSE   0typedef struct _Context_ {jmp_buf mainBuf;jmp_buf coBuf;int finish;struct {jmp_buf buf;int state;} thread[2];
} Context;Context gCtx;
static int next_thread;#define resume(i) \if (gCtx.thread[i].state==0) \{ \longjmp(gCtx.thread[i].buf, 1); \}#define yield() \if (0 == setjmp(gCtx.coBuf)) \{ \memcpy(gCtx.thread[thread_id].buf, gCtx.coBuf, sizeof(jmp_buf));\longjmp(gCtx.mainBuf, 1); \}void coroutine_function(void *arg)
{int n = 0;int thread_id = *(int *) arg;while (TRUE) {int i;if (++n > 10) break;printf("\n*** coroutine: thread_id=(%d) working \n", thread_id);for (i = 0; i < 10; ++i) {printf(".");}printf("\n*** coroutine: suspend \n");yield();}printf("\n*** coroutine: finish(%d)\n", n);gCtx.finish = 1;gCtx.thread[thread_id].state = 1;yield();
}typedef void (*pf) (void *);
BOOL start_coroutine(pf func, void *arg)
{int reserve[256];int thread_id;extern int run;thread_id = next_thread++;run = thread_id;func(&thread_id);return TRUE;
}void coroutine_main(void *arg)
{int i;int n = 0;int thread_id;thread_id = *(int *) arg;if (setjmp(gCtx.thread[thread_id].buf)!=0) goto next;start_coroutine(coroutine_function, NULL);next:while (TRUE) {if (gCtx.finish) break;printf("\n=== main() count(%d): thread_id=(%d) working \n", ++n, thread_id);for (i = 0; i < 10; ++i) {printf("%d%d%d%d%s", i, i, i, i, "-");}printf("\n=== main: suspend \n");yield();}printf("thread_id main=%d\n", thread_id);gCtx.thread[thread_id].state = 1;yield();
}int run;
int sched()
{int s;if (run == 0) s = 1; else s = 0;if (gCtx.thread[s].state == 0) run = s;return run;
}int main()
{int i;if (setjmp(gCtx.mainBuf)!=0) goto resched;start_coroutine(coroutine_main, NULL);while (TRUE) {resched:i = sched();printf("sched thread(%d) to run\n", i);if (gCtx.thread[i].state == 0) {resume(i);} else break;}printf("done\n");return 0;
}

子线程用start_coroutine()启动。下一个子线程必须用上一个子线程启动。子线程结束后不能return返回,而是把状态置为1,表示结束,然后用yield()回到调度程序。更多的子线程需要自行改进调度程序。自己看代码吧!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/48168.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【SpringBoot】测试Control接口方法

测试Controller接口方法: 执行单元测试: MockHttpServletRequest: HTTP Method POST Request URI /hello Parameters { } Headers [ Content-Type:"application/json;charsetUTF-8"] Body null Session Attrs { } Handler: Type com.weiz.helloworld.web.…

Nodejs—创建简易WebSocket通信过程详解

文章目录 安装NodejsWindows 安装Linux 源码安装 WebSocket简介WebSocket 与 AJAX 轮询的区别WebSocket的属性核心事件处理器 WebSocket使用示例设置 Node.js WebSocket 服务器创建客户端 HTML 页面运行 WebSocket 服务器和客户端 安装Nodejs Windows 安装 下载地址&#xff…

KTV点歌系统有什么作用?

在娱乐场所中&#xff0c;KTV点歌系统作为一种多功能的多媒体服务设施&#xff0c;为顾客提供了便捷的操作界面&#xff0c;使他们能够选择并播放自己喜爱的歌曲。本项目旨在构建一个高效且用户友好的KTV点歌系统&#xff0c;并不断进行优化以提升其性能和用户体验。尽管目前该…

发现FionaAI:免费体验最新的GPT-4o Mini模型!

你现在可以在FionaAI上免费体验OpenAI刚刚发布的GPT-4o Mini模型&#xff01;作为您在Google Chrome中的ChatGPT驱动助手&#xff0c;FionaAI可以随时随地与您对话&#xff0c;帮助您轻松创作和处理文本。 为什么选择GPT-4o Mini&#xff1f; 最新技术&#xff1a;GPT-4o Mini是…

8个特征工程技巧提升机器学习预测准确性

引言 对于机器学习从业者来说&#xff0c;掌握各种特征工程技巧是非常有帮助的。毕竟&#xff0c;特征是影响机器学习和深度学习模型实时表现的关键因素。在机器学习领域&#xff0c;提升模型预测准确性的关键之一是选择合适的特征&#xff0c;并剔除那些对模型性能影响不大的特…

git修改提交姓名

git config --global user.name “新用户名” git config --global user.email “新邮箱地址” 修改提交的用户名 git config --global user.name “yu***”

Vue 多选下拉框+下拉框列表中增加标签

1、效果图 2、代码部分 &#xff08;1&#xff09;代码 <el-select class"common-dialog-multiple multipleSelectStyle" change"clusterListChange" v-model"form.clusterId" placeholder"请先选择" multiple filterable defaul…

将本机的ssh密钥添加到git服务器中,要怎么实现?

前言 本文是该专栏的第2篇&#xff0c;后面将持续分享git的干货知识&#xff0c;记得关注。 本文&#xff0c;笔者将主要来介绍“针对“ssh密钥添加到git服务器”的相关方法。具体细节部分以及完整代码的实现以及思路&#xff0c;跟着笔者直接往下看正文内容。 正文 将本机的S…

web前端 Vue 框架面试120题(四)

面试题 61 . 简述Vue computed 和 watch 的区别和运用的场景 &#xff1f; 参考回答&#xff1a; 一、Computed 在Vue.js&#xff0c;computed 是一个非常有用的属性&#xff0c;它允许声明计算属性&#xff0c;这些属性会根据其依赖的数据进行自动更新&#xff0c;而无需手动…

【C++】STL-map的使用

目录 1、map的简述 2、map的使用 2.1 insert 2.2 operator*、operator-> 2.3 operator[] 3、multimap 1、map的简述 map与set一样是关联式容器 map就相当于二叉搜索树中的KV模型&#xff0c;底层是使用红黑树实现的&#xff0c;仿函数默认是less&#xff0c;即比根小…

为了Python换源,我开发了一个库「pipco 0.0.19」

你好&#xff0c;我是悦创。 有时候某个源又出问题&#xff0c;或者频繁切换源。我就想开发一个库可以切换的&#xff0c;链接&#xff1a;https://pypi.org/project/pipco/ 库是开源的&#xff0c;可以自行学习或者使用。 使用方法&#xff1a; 安装 pip install pipco查…

在 PostgreSQL 中如何实现数据的加密存储?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01;&#x1f4da;领书&#xff1a;PostgreSQL 入门到精通.pdf 文章目录 在 PostgreSQL 中如何实现数据的加密存储&#xff1f;一、为什么要进行数据加密存储&#xff1f;二、P…

如何证明员工有泄密行为,哪款软件可以提供这样的帮助?

如果员工泄密&#xff0c;如何证明员工有泄密行为&#xff1f; 证明员工有泄密行为通常需要以下几个步骤&#xff1a; 监控与记录&#xff1a;通过DLP&#xff08;数据防泄漏&#xff09;系统实时监控员工的行为&#xff0c;包括文件操作、数据传输、邮件发送等。分析行为&am…

解决git 不同branch 下node_moudes不同步的问题

可以使用工作树通过不同的分支管理项目&#xff0c;实际上就是创建不同的项目文件&#xff0c;分别安装不同的rely&#xff0c;可以多个终端分别运行。 git worktree add ../new-feature-branch new-feature这将在仓库的父目录中创建一个新的工作树目录 new-feature-branch&am…

RESTful API设计指南:构建高效、可扩展和易用的API

文章目录 引言一、RESTful API概述1.1 什么是RESTful API1.2 RESTful API的重要性 二、RESTful API的基本原则2.1 资源导向设计2.2 HTTP方法的正确使用 三、URL设计3.1 使用名词而非动词3.2 使用复数形式表示资源集合 四、请求和响应设计4.1 HTTP状态码4.2 响应格式4.2.1 响应实…

SQL Server性能监控秘籍:数据库性能计数器阈值设置指南

SQL Server性能监控秘籍&#xff1a;数据库性能计数器阈值设置指南 在SQL Server的运维和管理中&#xff0c;性能监控是确保数据库健康运行的关键环节。性能计数器提供了丰富的数据&#xff0c;帮助我们了解系统的状态和性能瓶颈。然而&#xff0c;如何设置性能计数器的阈值&a…

Linux中进程的控制

一、进程的创建 1、知识储备 进程的创建要调用系统接口&#xff0c;头文件 #include<unistd.h> 函数fork() 由于之前的铺垫我们现在可以更新一个概念 进程 内核数据结构&#xff08;task_struct, mm_struct, 页表....&#xff09; 代码 数据 所以如何理解进程的独…

C++进阶 之 【C++11】部分简单语法详细讲解(带你先入门学习C++11)

目录 一、C11简介 二、列表初始化 1.{} 初始化 2.std::initializer_list 三、变量类型推导 1.auto 2.decltype 3.nullptr 四、新增加容器---静态数组array、forward_list以及unordered系列 1.静态数组 array 2.单链表 forward_list 3.unordered_map 4.unordered_s…

pip使用(永久换源和恢复原源)

当我们使用pip下载python的各种包时可能会遇到下载错误和下载过慢。 更改 pip 源可以帮助加快包的安装速度&#xff0c;特别是在某些国内网络环境下。 1. 查看当前 pip 配置 首先&#xff0c;可以使用以下命令查看当前 pip 的配置信息&#xff1a; pip config list2. 选择合…

前端面试题(JS篇七)

一、SQL 注入攻击&#xff1f; SQL 注入攻击指的是攻击者在 HTTP 请求中注入恶意的 SQL 代码&#xff0c;服务器使用参数构建数据库 SQL 命令时&#xff0c;恶意 SQL 被一起构 造&#xff0c;破坏原有 SQL 结构&#xff0c;并在数据库中执行&#xff0c;达到编写程序时意料之外…