日常记录我的

多线程开发

2023年11月23日

16:41

c 语言中 主线程传递给子线程 参数 时 地址相同

c++  传递时不同 需要用ref , c++ 传递引用也是副本 不是同一个值 会执行拷贝函数(2次)。传递值会拷贝3次

多线程真是一个神奇的东西,

 主线程为 a   开辟 线程 b 中有list 存放传送给上层的消息  并且不断由a 给list 中存放数据 b 中发送后销毁数据

现有中断消息 f  需要上报 , 此刻 f 需要根据情况修正,如果 f 直接向上传递,中断 需要将list 中相关联的消息一起销毁掉

 如果 f 放入 list  中 等待发送 需要保证之前的数据也能发送成功 可是这就会和中断信号违背,要注意具体情况是要马上中断 还是中断标志。

线程中使用锁机制  要注意 死锁问题发生  锁的粒度尽量小 ,释放锁 要注意 函数 return  时  或者 循环时 要注意释放的时机

读写锁           可以多个读 但是只能一个写  写的时候不能读 读的时候不能写

互斥锁          一次只有一个锁执行  锁失败 线程睡眠   后续不可知

自旋锁          一次只有一个锁执行  锁失败 线程等待   上一个结束 马上轮到我 自旋锁比较适用于锁使用者保持锁时间比较短的情况。

正是由于自旋锁使用者一般保持锁时间非常短,因此选择自旋而不是睡

眠是非常必要的。容易死锁 限定自旋时间或者次数

在锁的频繁释放和增加情况下要注意 变量 的使用 有可能出现内存地址相同的问题,导致在未释放数据存放list 中查找出错误信息。

多客户端连接服务器开发 目前主要是 通过多线程实现   即  每当有客户端连接 server端时开启一个线程实现连接和接收信息 然后存储 socket  到列表

发送数据时 可以通过循环查询列表 发送   这样就多个客户端连接可以实现一个线程发送   recv 是阻塞的 会等待数据  

线程是在start()方法被调用后开始运行的,而不是在join()方法被调用后运行。

当你创建并启动一个线程时,你通常会调用线程对象的start()方法来开始执行线程。此时,线程会独立于主线程(即调用start()的线程)运行。一旦线程开始运行,它将一直运行,直到完成其任务或遇到异常。

join()方法用于等待线程完成执行。当你调用一个线程对象的join()方法时,调用该方法的线程(通常是主线程)将被阻塞,直到被调用的线程完成执行。这意味着,join()方法用于确保主线程等待子线程完成其任务后再继续执行。

因此,线程是在start()方法被调用后开始运行的,并在join()方法被调用之前一直运行

来自 <文心一言>

多线程传输  时 如果 占用率高的  持续的事件 可以单独开一个线程 ,不和其他事件混合,

通信  多线程 开发 

每个会话者开辟一个线程     适用于少量会话

会话者合并 从功能的角度出发 每个功能开辟一个线程 ,如 发送 ,接收 ,检查在线 。  适用于大量会话 当然 其他细节 如 线程调度 资源利用 需要根据情况开发

Epoll  模式  

Poll  模式

Select  模式

多线程开发

2023年11月23日

16:41

c 语言中 主线程传递给子线程 参数 时 地址相同

c++  传递时不同 需要用ref , c++ 传递引用也是副本 不是同一个值 会执行拷贝函数(2次)。传递值会拷贝3次

多线程真是一个神奇的东西,

 主线程为 a   开辟 线程 b 中有list 存放传送给上层的消息  并且不断由a 给list 中存放数据 b 中发送后销毁数据

现有中断消息 f  需要上报 , 此刻 f 需要根据情况修正,如果 f 直接向上传递,中断 需要将list 中相关联的消息一起销毁掉

 如果 f 放入 list  中 等待发送 需要保证之前的数据也能发送成功 可是这就会和中断信号违背,要注意具体情况是要马上中断 还是中断标志。

线程中使用锁机制  要注意 死锁问题发生  锁的粒度尽量小 ,释放锁 要注意 函数 return  时  或者 循环时 要注意释放的时机

读写锁           可以多个读 但是只能一个写  写的时候不能读 读的时候不能写

互斥锁          一次只有一个锁执行  锁失败 线程睡眠   后续不可知

自旋锁          一次只有一个锁执行  锁失败 线程等待   上一个结束 马上轮到我 自旋锁比较适用于锁使用者保持锁时间比较短的情况。

正是由于自旋锁使用者一般保持锁时间非常短,因此选择自旋而不是睡

眠是非常必要的。容易死锁 限定自旋时间或者次数

在锁的频繁释放和增加情况下要注意 变量 的使用 有可能出现内存地址相同的问题,导致在未释放数据存放list 中查找出错误信息。

多客户端连接服务器开发 目前主要是 通过多线程实现   即  每当有客户端连接 server端时开启一个线程实现连接和接收信息 然后存储 socket  到列表

发送数据时 可以通过循环查询列表 发送   这样就多个客户端连接可以实现一个线程发送   recv 是阻塞的 会等待数据  

线程是在start()方法被调用后开始运行的,而不是在join()方法被调用后运行。

当你创建并启动一个线程时,你通常会调用线程对象的start()方法来开始执行线程。此时,线程会独立于主线程(即调用start()的线程)运行。一旦线程开始运行,它将一直运行,直到完成其任务或遇到异常。

join()方法用于等待线程完成执行。当你调用一个线程对象的join()方法时,调用该方法的线程(通常是主线程)将被阻塞,直到被调用的线程完成执行。这意味着,join()方法用于确保主线程等待子线程完成其任务后再继续执行。

因此,线程是在start()方法被调用后开始运行的,并在join()方法被调用之前一直运行

来自 <文心一言>

多线程传输  时 如果 占用率高的  持续的事件 可以单独开一个线程 ,不和其他事件混合,

通信  多线程 开发 

每个会话者开辟一个线程     适用于少量会话

会话者合并 从功能的角度出发 每个功能开辟一个线程 ,如 发送 ,接收 ,检查在线 。  适用于大量会话 当然 其他细节 如 线程调度 资源利用 需要根据情况开发

Epoll  模式  

Poll  模式

Select  模式

音视频开发

2023年11月23日

16:40

音频信息设置要注意  可能回合视频帧分开给 ,要防止覆盖导致 设置失败

视频帧 要注意 帧率 宽高  编码格式  时间戳

音频帧  采样率  声道   采样频率  

要保证视频头 的正确性。  视频头 包含了 整个视频的解析信息 ,如音频类型 ,频率 ,采样率 ,位数 视频编码类型 ,视频分辨率 ,

如果视频没有声音 可能是因为 音频信息缺失  ,

视频定位 失败 可能是 时间磋  和帧号 问题

开发音视频如果视频有问题要通过分析流数据来判断 

客户端和服务端是否一致

是否丢帧 

视频开发实时预览时要做好属性检查 ,如果属性变化要重新拉流。

开发外部厂家的音视频 可能存在sdk 的不兼容 或者sdk 需要更新才支持接口

天地音视频 多采用 异步回调 。。

异步回调能够快速响应 ,结果,将持续的事件独立出来 ,采用回调来执行后续事件

Ps 流  该流包含特殊信息 需要解码   e0  是视频 c0 是音频

H264  流  就是裸流 里面不包含其他信息 区分音视频 类别

天地流  需要一个头信息  才能正确解析

音视频数据每帧时间间隔如果有差异会影响音频播放卡顿,导致音频中断

音视频帧正常是每一帧视频都有对应的一帧音频

测试项 关键点

预览 过程中改变视频参数 是否能够完成重连

回放  多画面 倍速  时间回放 文件回放 定位

下载 多路下载   时间下载 文件下载 , 下载文件大小是否一致  连续下载

上墙  回放上墙  预览上墙  

丢帧 花屏 跳秒  声音

Valgraind  内存检测。

影视片开发流控管理

数据发送失败 要存入数据再次尝试发送 ,不能丢帧   数据缓存要注意 不能无限缓存数据 容易导致服务器内存奔溃

获取音视频数据     分析数据  音频帧 |视频帧   音频帧不单独发 需要和视频帧一起发送  所以会先缓存音频帧  人,然后等等待视频帧的到来。  封装天地视频格式时要注意是否将音视频信息属性完善 ,帧号时间戳 是否正确  

视频定位 主要 依据视频中的时间戳 如果没有一个固定变化的时间戳 无法完成定位。

网络协议

2023年11月14日

9:11

Ipv6   ping6  xxxx

Ipv4  ping xxxx

服务器开启双栈  可以同时支持 ipv6  和ipv4的请求

网络协议是一组双方约定好的特定的的传输字符片段和机制。

环境变量  动态包 依赖

建立连接 绑定ip 端口是否开放。

tcp连接数据 线程开启必要性,连接过程实现(模拟三次握手)  心跳机制 。  异步/同步数据发送 的不同处理方式

线程共用 。  通常是通过共同处理同一个数据容器来实现 ,如 循环同一个链表数据做处理

设备断开重连机制 

绑定读取回调  (巧用回调)

绑定写入回调(在大量数据传输中  将数据缓存,等待连接空闲发送数据)

提取公共函数 降低耦合 (不要省事)

数据越界 。。 包粘连   数据发送不全  strcpy 慎用。

常用调试方法 :  gdb(主要)  tcpdump  log 

c 语言 --内存管理- 非正常流程结束  释放资源要慎重。通常情况下只处理本函数开辟的空间  不要乱释放 也不要不释放。

返回指针地址 作为句柄 时  返回内存地址   可能存在地址 快速开辟和关闭导致地址相同的情况

结合上层业务,判断协议sdk 开发的什么程度

工具函数 要和业务逻辑解耦

发送信息 考虑 :解析session  之类的 需要 考虑 。是否需要  不要让发送信息逻辑 夹杂太多其他的逻辑

          同步 要等待数据

         异步 不等待接受数据 时 考虑如何回收消息,并处理

接受数据 :  接收数据的量 不代表读取数据的量   需要循环读取 直至 全部读取完数据。

原有功能开发 要保证原有函数参数的意义一致,

消息滞后 逻辑可通过线程完成异步。

代码逻辑可以自上而下编写 也要考虑自下而上的写法  例如 通过 type 得到最终发送数据 也可以通过最终数据向上推到type  然后 拼装数据发送

## 代码设计 整体实现 同一块业务代码适配不同类型模块 可以通过预制函数指针实现 后续各个模块通过重写函数,绑定函数指针不影响业务整体流程。

*** tcp   协议

滑动窗口机制 

断开连接时 会有 close_time  收到最后的确认断开应答

 和wait_time   关闭时等待发送方将完整数据发送完毕 因为tcp 的滑动窗口机制

udp 协议没有发送缓存区

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值