多核编程4种方式:多线程、多进程、csp(轻量级线程)、actor(轻量级进程)

2024-03-28 16:32

本文主要是介绍多核编程4种方式:多线程、多进程、csp(轻量级线程)、actor(轻量级进程),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1)多线程方式利用多核心
    锁(信号量、互斥锁、自旋锁、读写锁、原子锁cas、乐观锁、悲观锁)
        锁的粒度
        什么情况下用什么锁,比较困惑

    消息队列

    管道(不需要加锁): pipe+epoll/select/epoll

    资源+锁

    并发实体:线程

    总结:
        需要大量的锁。

2)多进程方式利用多核心
    共享内存

    pipe管道、
        父进程fork子进程有限制
        只能一端读一端写
        数据是单向的

    socket:
        一般用这种来
        用epoll

    信号

    并发实体:进程。

    总结:


3)csp模型
    go语言:
        并发实体:goroutine(协程,用channel来通信)。
        协程是轻量级的线程。
        协程切换比较轻量,是开发者自己调度的。
        线程切换需要进程,进程切换需要。

    总结:
        优化多线程的编程方式。

4)actor
    erlang: 
        语言层面实现actor模型。
        把actor命名为进程,actor是轻量级的进程。

    skynet:
        从框架层面实现actor。


    actor由程序来调度,比较轻量。

    提几个问题:
        1.actor之间是如何沟通的?
            统一性差,隔离性强。
            独立的运行环境。
            a actor和b actor沟通,就发送到对方的消息队列中。
                多进程是socket沟通,其实也是消息的方式。

        2.actor是怎么运行的?
            多进程中,有一个主线程,通过os调度来运行。
            actor中,当消息队列中有消息的时候,就可以运行:
                多个线程,消耗actor消息。 工作线程。轮训,消息队列取出消息,并在actor
                    环境中运行了。
                取出消息,并且调用回调函数。

        3.actor是如何调度的呢?
            不是每个actor都有消息。这个怎么处理呢?
                全局消息队列。把actor中的消息插入全局消息队列,指针的方式。
                通过多线程消费全局消息队列的方式来调度actor,这样范围缩小,效率提高。

                将有消息的消息队列放入全局消息队列中,工作线程只需要轮训全局消息队列,
                    就可以对整个actor消息进行调度了。

        4.actor怎么接收网络中的数据?
            fd和actor绑定

            epoll_create
                红黑树+就绪队列
            epoll_ctrl
                epoll_event, fd, actor_id 
            epoll_wait(ev[])
                取出一个数组
                ev[].data.ptr -->actorid, fd--》找到actor--》网络线程发送数据到actor

        5.如何使用skynet?
            agent--》玩家actor
            hall--》大厅actor
            main--》启动actor
            redis---》玩家不能退出,重新进去要保存数据。 redis actor
            room--》房间actor,3人一个房间组成的actor

            ./skynet/skynet config.test
                main
                redis
                hall


            把功能拆分成多个actor, 热点拆分为多个actor,
                 一个actor就是一个统一性较差的环境。

            架构:
                main:网关--》listenfd
                agent: connedfd--》其它数据全部由agent进行处理
                    游戏是相同的,我们不能放到一个actor中处理,而要创建很多个节点,充分利用cpu
                    每一个client都有一个agent
                hall:保存匹配队列的--》大厅
                    每一个agent与hall连接
                    hall去创建一个room actor


                skynet中的2种调用方式:    
                    send:消息队列send,异步调用。
                    call--》rpc: 阻塞,同步调用。

            指导思想: 简单可用,逐步优化,忌讳过度优化


            逻辑的完备性
                

            actor:
                隔离的环境(lua或内存块)
                回调函数
                消息队列

            单线程来处理的        

            让工作线程去轮训只有消息的actor

    总结:
        优化的是多进程的解决方案。
        

---------------------------
并发编程的2个考虑:

    隔离性
        运行环境隔离:
            多线程隔离性差、统一性高

    统一性
        数据的统一


------------------------------
分布式:
    C:一致性
    A:可用性
    P:分区容错性


----------------------
源码:
    nginx
    redis
    skynet
    zeromq

造轮子:
    中间件:
        内存池
        线程池
        连接池
        消息队列

    高并发IO:
        epoll
        reactor
        proactor

    网络协议栈:
        用户态,实现百万连接

    nginx模块开发

    并发设计

    集群能力:
        数据库的集群。
        zookeeper的集群--》多进程的管理。

    linux内核编程:
        网卡子系统的编程
        内存管理
        进程间通信
        内核的编译

    性能测试:
        数据库的索引优化和sql优化。
        linux调优、内存调优。

    部署能力:
        docker


    一线架构

这篇关于多核编程4种方式:多线程、多进程、csp(轻量级线程)、actor(轻量级进程)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/856120

相关文章

gitlab安装及邮箱配置和常用使用方式

《gitlab安装及邮箱配置和常用使用方式》:本文主要介绍gitlab安装及邮箱配置和常用使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1.安装GitLab2.配置GitLab邮件服务3.GitLab的账号注册邮箱验证及其分组4.gitlab分支和标签的

C++中零拷贝的多种实现方式

《C++中零拷贝的多种实现方式》本文主要介绍了C++中零拷贝的实现示例,旨在在减少数据在内存中的不必要复制,从而提高程序性能、降低内存使用并减少CPU消耗,零拷贝技术通过多种方式实现,下面就来了解一下... 目录一、C++中零拷贝技术的核心概念二、std::string_view 简介三、std::stri

Linux脚本(shell)的使用方式

《Linux脚本(shell)的使用方式》:本文主要介绍Linux脚本(shell)的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录概述语法详解数学运算表达式Shell变量变量分类环境变量Shell内部变量自定义变量:定义、赋值自定义变量:引用、修改、删

python判断文件是否存在常用的几种方式

《python判断文件是否存在常用的几种方式》在Python中我们在读写文件之前,首先要做的事情就是判断文件是否存在,否则很容易发生错误的情况,:本文主要介绍python判断文件是否存在常用的几种... 目录1. 使用 os.path.exists()2. 使用 os.path.isfile()3. 使用

LiteFlow轻量级工作流引擎使用示例详解

《LiteFlow轻量级工作流引擎使用示例详解》:本文主要介绍LiteFlow是一个灵活、简洁且轻量的工作流引擎,适合用于中小型项目和微服务架构中的流程编排,本文给大家介绍LiteFlow轻量级工... 目录1. LiteFlow 主要特点2. 工作流定义方式3. LiteFlow 流程示例4. LiteF

SpringBoot集成LiteFlow实现轻量级工作流引擎的详细过程

《SpringBoot集成LiteFlow实现轻量级工作流引擎的详细过程》LiteFlow是一款专注于逻辑驱动流程编排的轻量级框架,它以组件化方式快速构建和执行业务流程,有效解耦复杂业务逻辑,下面给大... 目录一、基础概念1.1 组件(Component)1.2 规则(Rule)1.3 上下文(Conte

Mybatis的分页实现方式

《Mybatis的分页实现方式》MyBatis的分页实现方式主要有以下几种,每种方式适用于不同的场景,且在性能、灵活性和代码侵入性上有所差异,对Mybatis的分页实现方式感兴趣的朋友一起看看吧... 目录​1. 原生 SQL 分页(物理分页)​​2. RowBounds 分页(逻辑分页)​​3. Page

Windows的CMD窗口如何查看并杀死nginx进程

《Windows的CMD窗口如何查看并杀死nginx进程》:本文主要介绍Windows的CMD窗口如何查看并杀死nginx进程问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录Windows的CMD窗口查看并杀死nginx进程开启nginx查看nginx进程停止nginx服务

Java中实现线程的创建和启动的方法

《Java中实现线程的创建和启动的方法》在Java中,实现线程的创建和启动是两个不同但紧密相关的概念,理解为什么要启动线程(调用start()方法)而非直接调用run()方法,是掌握多线程编程的关键,... 目录1. 线程的生命周期2. start() vs run() 的本质区别3. 为什么必须通过 st

Linux链表操作方式

《Linux链表操作方式》:本文主要介绍Linux链表操作方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、链表基础概念与内核链表优势二、内核链表结构与宏解析三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势六、典型应用场景七、调试技巧与