标签: linuxc 1.pthread_create函数 函数原型:int pthread_create(pthread_t *tid, const pthread_attr_t *tattr, void*(*start_routine)(void *), void *arg); 功能:创建一个新的线程,并将线程加入当前进程 头文件:#include pthread并非linux系统的默认库,需要手动链接 -线程库 -lpthread 参数: tid:指向线程标识符的指针 tattr:设置线程属性,可由pthread_attr_init()函数创建默认属性对象 start_routine:线程运行函数的起始地址,注意start_route的返回值地址必须无效 arg:运行函数的参数,arg首选动态堆上分配内存(进程,这样资源可以由程序控制回收),从栈上(线程)分配内存可能导致地址无效或在线程终止时地址被重新分配。 线程函数有多个参数的情况:申明一个结构体来包含所有的参数,然后将结构体传入线程函数。 继续阅读 >>


胡锦雲 19/01/20 22:17:02
redis 使用到的位域 今天在看redis源码的时候在3.0版本的redis.h 文件中发现了这样的几行代码,看了有趣,研究了一番,才发现这个东西就是c语言中的位域。 /* * redisObject Redis对象 */ typedef struct redisObject { unsigned type : 4; // 类型 unsigned encoding : 4; // 编码 unsigned lru : REDIS_LRU_BITS; // 对象最后一次被访问的时间 int refcount; // 引用计数 void *ptr; // 指向实际值的指针 } robj; 关于这个概念,整理的内容有以下部分。 什么是位域 有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位。例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可。为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为“位域”或“位段”。所谓“位域” 继续阅读 >>


刘嘉辉 19/01/20 21:32:19
注:博客内容主要摘抄自参考阅读中的两篇博文~ 前言 最近在翻阅《阿里巴巴Java开发手册》时发现了这样一条【推荐】性的原则: // 使用索引访问用 String 的 split 方法得到的数组时,需做最后一个分割符后有无内容的检查,否则会有抛 IndexOutOfBoundsException 的风险。 String str = "a,b,c,,"; String[] ary = str.split(","); // 预期大于 3,结果是 3 System.out.println(ary.length); 比较好奇产生上述结果的原因,因此决定分析一波源码。 简介 split(String regex, int limit)一般根据正则表达式分割字符串,limit限定分割后产生的字符串个数,超过数量限制的情况下前 limit-1 个子字符串正常分割,最后一个子字符串包含剩下的所有字符。重载方法split(String regex)将 limit 设置为 0。 public String[] split 继续阅读 >>


董恒毅 19/01/20 20:40:14
文章目录BUG 描述set / map 的 insert / emplace 的返回值set / map 的去重于是 BUG 就诞生了 :strict weak ordering!!! BUG 描述 记录一个纠结了一天的 BUG: 向 set 容器中添加自定义类, 然后发现并没有添加进去, 真的是头大, 排查发现告诉我已经有相同 key 值元素存在了, 可我明明两个值不同 set / map 的 insert / emplace 的返回值 c++11 标准引入了 emplace, 与 insert 相对应. empalce 操作构造而不是拷贝元素。 当我们调用 insert 时, 我们将元素类型的对象传递给它们, 这些类型被拷贝到容器中 当我们调用 emplace, 会在容器管理的内存空间内直接创建对象。 注: emplace 的参数根据元素的类型变化, 参数必须与元素类型的构造函数相匹配 insert 和 emplace 只有在关键值 key 在容器中不存在时, 才会把该元素插入容器中, 否则如果 继续阅读 >>


吕子健 19/01/20 00:36:29
文章目录前言进程概念线程概念地址空间通信手段调度和切换进程何时调度线程切换进程的创建过程fork 函数task_struct父子进程间的文件共享线程的实现一对一模型 (内核级线程) 1:1多对一模型 (用户级线程) M:1多对多模型 两级模型 M:N 前言 书本上的定义: 线程是调度的基本单位, 进程是资源分配的基本单位 应该大家都知道这个概念, 但是进程和线程之间的异同绝不仅仅是这一句话这么简单 进程概念 进程是由正文段 (存放被执行的机器指令), 用户数据段 (存放进程在执行时直接进行操作的所有数据, 包括进程使用的全部变量在内), 系统数据段 (存放程序运行的环境) 而这个所谓的系统数据段也正是进程中最重要的一部分, 它就是进程和程序的区别所在, 进程作为一个动态的程序实例, 这一部分就存放着进程的控制信息, 每个进程都有一个 task_strust 数据结构 (也就是 PCB) 来存放这些控制信息. 操作系统也是通过这些控制信息 (task_struct) 来控制调度所有进程的 线程概念 继续阅读 >>


吕子健 19/01/19 20:36:07
5. 共享栈模式 这种做法有什么好处?其实我们可以直接想想以前的方法(每个协程单独分配栈)有什么坏处好了: 以前的方法为每个协程都单独分配一段内存空间,因为是固定大小的,实际使用中协程并不能使用到这么大的内存空间,于是就会造成非常大的内存浪费(有同学一定会问为什么不用 Split Stack ,这个东西的性能有多垃圾有目共睹)。而且因为绝大多数协程使用的栈空间都极少,复制栈空间的开销非常小。 因为协程的调度是非抢占的(non-preempt),而在 libco 中,切换的时机都是做 I/O 的时候,并且只有在切换的时候才会去复制栈空间,所以开销也可控。 具体原理:我们一步步来看其调用,从其中明白他的原理 在协程环境初始化时,要先调用 (co_alloc_sharestack) 来分配共享栈的内容,其中第一个参数 count 是指分配多少个共享栈,stack_size 是指每个栈的大小 ,分配出来的结构名是 stShareStack_t 。 stShareStack_t 结构 继续阅读 >>


刘生玺 19/01/19 16:15:40
写机器学习相关的博客时,插入一些复杂的数学公式是不可避免的事,总是截图并不是一个完美的解决方法,在此总结一下如何使用LaTeX编辑数学公式,包括常用的符号,以及机器学习经常用到的公式。 什么是LaTeX LaTeX(LATEX,音译“拉泰赫”)是一种基于ΤΕΧ的排版系统,由美国计算机学家莱斯利·兰伯特(Leslie Lamport)在20世纪80年代初期开发,利用这种格式,即使使用者没有排版和程序设计的知识也可以充分发挥由TeX所提供的强大功能,能在几天,甚至几小时内生成很多具有书籍质量的印刷品。对于生成复杂表格和数学公式,这一点表现得尤为突出。因此它非常适用于生成高印刷质量的科技和数学类文档。这个系统同样适用于生成从简单的信件到完整书籍的所有其他种类的文档。 LaTeX编辑数学公式基本语法元素 排版方式 行间公式(inline):用$...$将公式括起来。 例如:输入$x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}$显示:x=−b±b2−4ac2ax = \frac 继续阅读 >>


冯鑫 19/01/18 22:26:24
LRU和LFU LRU是最近最少使用页面置换算法(Least Recently Used),也就是首先淘汰最长时间未被使用的页面! LFU是最近最不常用页面置换算法(Least Frequently Used),也就是淘汰一定时期内被访问次数最少的页! frist,如何使用链表实现LRU(简单) 我们维护一个有序单链表,越靠近链表尾部的结点是越早之前访问的。当有一个新的数据被访问时,我们从链表头开始顺序遍历链表。 如果此数据之前已经被缓存在链表中了,我们遍历得到这个数据对应的结点,并将其从原来的位置删除,然后再插入到链表的头部。 如果此数据没有在缓存链表中,又可以分为两种情况: 如果此时缓存未满,则将此结点直接插入到链表的头部 如果此时缓存已满,则链表尾结点删除,将新的数据结点插入链表的头部。 这样我们就用链表实现了一个 LRU 缓存,是不是很简单? #include <iostream> #include <list> #include <vector&g 继续阅读 >>


刘生玺 19/01/18 15:41:25
1. BST的后序遍历序列 题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同 后序遍历(左右根).最后一个节点一定是整个树的根节点,根据树与递归的关系,泛化而讲,他会是树的根节点(包括左子树,右子树等等).所以我们的思路就是先找到根,然后判断前部分(相当于左子树)是否小于根,后部分(相当于右子树)是否大于根即可 class Solution { public: bool VerifySquenceOfBST(vector<int> sequence) { int sz = sequence.size(); if (sz == 0) return false; return IsBST(sequence, 0, sz - 1); } //第一部分是左子树结点的值,它们都比根结点的值小 b 继续阅读 >>


刘生玺 19/01/14 18:11:23
散列思想 散列表就是我们平常说的哈希表,英文名叫"Hash Table",其基础依据就是: 散列表用的是数组支持按照下标随机访问数据的特性,所以散列表其实就是数组的一种扩展,由数组演化而来。可以说,如果没有数组,就没有散列表。 这里还是直接使用老师的例子来说事吧.中间添加自己的思想就行了.自己想例子又得半天,而且我们的目标也不是想一个好例子,而是真正理解并掌握知识.对吧? 用一个例子来解释一下。假如我们有 89 名选手参加学校运动会。为了方便记录成绩,每个选手胸前都会贴上自己的参赛号码。这 89 名选手的编号依次是 1 到 89。现在我们希望编程实现这样一个功能,通过编号快速找到对应的选手信息。你会怎么做呢? 我们可以把这 89 名选手的信息放在数组里。编号为 1 的选手,我们放到数组中下标为 1 的位置;编号为 2 的选手,我们放到数组中下标为 2 的位置。以此类推,编号为 k 的选手放到数组中下标为 k 的位置。 因为参赛编号跟数组下标一一对应,当我们需要查询参赛编号为 x 的选手的时候,我们只需 继续阅读 >>


刘生玺 19/01/14 18:00:26