pthread

UNIX环境编程学习笔记(26)——多线程编程(一):创建和终止线程

风格不统一 提交于 2020-01-24 21:10:01
lienhua34 2014-11-08 在 进程控制三部曲 中我们学习了进程的创建、终止以及获取终止状态等的进程控制原语。线程的控制与进程的控制有相似之处,在表 1中我们列出了进程和线程相对应的控制原语。 表 1: 进程原语和线程原语的比较 进程原语 线程原语 描述 fork pthread_create 创建新的控制流 exit pthread_exit 从现有的控制流中退出 waitpid pthread_join 从控制流中得到退出状态 atexit pthread_cleanup_push 注册在退出控制流时调用的函数 getpid pthread_self 获取控制流的 ID abort pthread_cancel 请求控制流的非正常退出 1 线程 每个线程都有一个线程 ID,线程只在它所属的进程环境中有效。线程ID 使用pthread_t 表示。可以通过调用pthread_self 函数获取线程自身的线程 ID, #include <pthread.h> pthread_t pthread_self(void); 返回值:调用线程的线程ID 线程 ID 不一定是一个非负整数,也有可能是一个结构体。所以,要对比两个线程是否相同,必须使用pthread_equal 函数来进行, #include <pthread.h> int pthread_equal(pthread

pthread线程知识要点

匆匆过客 提交于 2020-01-22 14:49:43
pthread线程知识要点 线程之间通信的两个基本问题是互斥和同步。` #include<pthread.h> 一、pthread_create 1、函数原型 int pthread_create(pthread_t tidp,const pthread_attr_t attr,(void )( start_rtn)(void ),void arg); 2、函数功能: pthread_create是类Unix操作系统(Unix、Linux、Mac OS X等)的创建线程的函数。 它的功能是创建线程(实际上就是确定调用该线程函数的入口点),在线程创建以后,就开始运行相关的线程函数。 返回成功时,由tidp指向的内存单元被设置为新创建线程的线程ID。attr参数用于指定各种不同的线程属性。 新创建的线程从start_rtn函数的地址开始运行,该函数只有一个万能指针参数arg, 如果需要向start_rtn函数传递的参数不止一个,那么需要把这些参数放到一个结构中,然后把这个结构的地址作为arg的参数传入。 3、返回值: 表示成功,返回0;表示出错,返回-1。 4、参数 第一个参数为指向线程标识符的指针。 第二个参数用来设置线程属性。 第三个参数是线程运行函数的起始地址。 最后一个参数是运行函数的参数。 示例: // 线程的运行函数 void say_hello(void args) {

腾讯后台开发面试笔试C++知识点参考笔记

馋奶兔 提交于 2020-01-21 00:15:23
文章是由自己笔试面试腾讯的笔记整理而来,整理的时候又回顾了一遍,中间工作忙断断续续整理了半个月,才完成现在的样子。主要是针对面试的C++后台开发岗位,涵盖了大部分C++相关的可能会被问到的技术点,作为面试技术的参考回头查阅。 这篇笔记是基础C++知识点总结,没有过多的阐述后台开发的系统架构和分布式后台服务设计相关,还有c++11新特性,这些笔试面试也会被问到但不在这篇讨论范围,可以关注专栏后面如果有机会再补上。 为什么析构函数要是虚函数? 基类指针可以指向派生类的对象(多态性),如果删除该指针delete []p;就会调用该指针指向的派生类析构函数,而派生类的析构函数又自动调用基类的析构函数,这样整个派生类的对象完全被释放。如果析构函数不被声明成虚函数,则编译器实施静态绑定,在删除基类指针时,只会调用基类的析构函数而不调用派生类析构函数,这样就会造成派生类对象析构不完全。所以,将析构函数声明为虚函数是十分必要的。 gdb调试命令 step和next的区别? 当前line有函数调用的时候,next会直接执行到下一句 ,step会进入函数. 查看内存 (gdb)p &a //打印变量地址 gdb)x 0xbffff543 //查看内存单元内变量 0xbffff543: 0x12345678 (gdb) x /4xb 0xbffff543 //单字节查看4个内存单元变量的值

pthread 的几个结构体

牧云@^-^@ 提交于 2020-01-20 04:07:07
http://blog.csdn.net/yangzhongxuan/article/details/7397139 /* Copyright (C) 2002,2003,2004,2005,2006,2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the

double buffer 实现

眉间皱痕 提交于 2020-01-19 01:59:04
1. 背景 字典或者模型加载经常会用到双buffer这样读多写少的数据结构。这里介绍一个从百度的brpc拿出来的一个双buffer实现。 2. 痛点 经常会遇到的是一个读远多于写的数据结构:大部分时候,所有线程从一个不变的server列表中选取一台server。如果server列表真是“不变的”,那么选取server的过程就不用加锁,我们可以写更复杂的分流算法。一个方法是用读写锁,但当读临界区不是特别大时(毫秒级),读写锁并不比mutex快,而实用的分流算法不可能到毫秒级,否则开销也太大了。另一个方法是双缓冲,很多检索端用类似的方法实现无锁的查找过程,它大概这么工作: 数据分前台和后台。 检索线程只读前台,不用加锁。 只有一个写线程:修改后台数据,切换前后台,睡眠一段时间,以确保老前台(新后台)不再被检索线程访问。 这个方法的问题在于它假定睡眠一段时间后就能避免和前台读线程发生竞争,这个时间一般是若干秒。由于多次写之间有间隔,这儿的写往往是批量写入,睡眠时正好用于积累数据增量。 但这套机制对“server列表”不太好用:总不能插入一个server就得等几秒钟才能插入下一个吧,即使我们用批量插入,这个"冷却"间隔多少会让用户觉得疑惑:短了担心安全性,长了觉得没有必要。我们能尽量降低这个时间并使其安全么? 3. 实现方式 我们需要写以某种形式和读同步,但读之间相互没竞争。一种解法是

Linux 线程编程2.0——线程同步-互斥锁

落花浮王杯 提交于 2020-01-17 13:52:54
当我们需要控制对共享资源的存取的时候,可以用一种简单的加锁的方法来控制。我们 可以创建一个读 / 写程序,它们共用一个共享缓冲区,使用互斥锁来控制对缓冲区的存取。     函数 pthread_mutex_init() 用来生成一个互斥锁。其函数原型如下: #include<pthread.h> int pthread_mutex_init(pthread_mutex_t *restrict mutex , const pthread_mutexattr_t *restrict attr) ; 第一个参数是互斥变量的地址,第二个参数设置互斥变量的属性,大多数情况下 . 选择 默认属性,则传入空指针 NULL 。   Pthread_mutex_lock() 函数声明开始用互斥锁上锁,此后的代码直至调用 pthread _mutex_ unlock() 为止,均被上锁,即同一时间只能被一个线程调用执行。当一个线程执行 到 pthread_mutex_lock() 处时,如果该锁此时被另一个线程使用,那么此线程被阻塞,线 程一直阻塞知道另一个线程释放此互斥锁。这两个函数原型是:  int pthread_mutex_lock(pthread_mutex_t *mutex) ;  int pthread_mutex_unlock(pthread_mutex_t *mutex) ;  

C++线程池的实现

喜夏-厌秋 提交于 2020-01-17 10:39:15
线程池 ,简单来说就是有一堆已经创建好的线程(最大数目一定),初始时他们都处于空闲状态,当有新的任务进来,从线程池中取出一个空闲的线程处理任务,然后当任务处理完成之后,该线程被重新放回到线程池中,供其他的任务使用,当线程池中的线程都在处理任务时,就没有空闲线程供使用,此时,若有新的任务产生,只能等待线程池中有线程结束任务空闲才能执行,下面是线程池的工作原理图: 我们为什么要使用线程池呢? 简单来说就是线程本身存在开销,我们利用多线程来进行任务处理,单线程也不能滥用,无止禁的开新线程会给系统产生大量消耗,而线程本来就是可重用的资源,不需要每次使用时都进行初始化,因此可以采用有限的线程个数处理无限的任务。 废话少说,直接上代码 首先是用条件变量和互斥量封装的一个状态,用于保护线程池的状态 condition.h 1 #ifndef _CONDITION_H_ 2 #define _CONDITION_H_ 3 4 #include <pthread.h> 5 6 //封装一个互斥量和条件变量作为状态 7 typedef struct condition 8 { 9 pthread_mutex_t pmutex; 10 pthread_cond_t pcond; 11 }condition_t; 12 13 //对状态的操作函数 14 int condition_init

8.线程与互斥量

[亡魂溺海] 提交于 2020-01-16 11:06:40
一.基本概念 进程中有哪些资源: 代码段指令,只读段,全局段,静态数据,段,堆,栈,命令行参数,环境变量表,代码的执行者(线程)。 线程:在进程中,负责执行代码的一个单位,它是进程的一部分,一个进程至少要有一个线程(主线程),进程也可以有多个线程(创建) 线程中的代码段指令,只读段,全局段,静态数据,段,堆,命令行参数,环境变量表,文件描述符,信号处理函数,等资源共享 线程之间,栈空间是私有的 线程是进程的一个实体,是操作系统独立调度和分派任务的基本单位。 二.POSIX线程 Unix和Linux是天生骄傲(不支持线程),通过添加额外的线程库可以使用 ,在编译多线程代码时需要添加 -lpthread,头文件pthread.h 对线程的操作: 创建线程 销毁线程 分离线程 联合线程 查询线程属性 设置线程属性 对于线程来说,最重要的是解决脏数据问题(线程同步),对于进程来说,解决通信问题(IPC) 三.创建线程 int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg); 功能:创建线程 thread:返回值,获取线程id attr:参数,设置线程属性 start_routine:参数,线程的入口函数 arg

进程间锁

帅比萌擦擦* 提交于 2020-01-15 01:30:29
目录 15.1 进程间pthread_mutex 15.2 文件锁 15.1 进程间互斥锁 直接上原语吧: # include <pthread.h> int pthread_mutexattr_init ( pthread_mutexattr_t * attr ) ; int pthread_mutexattr_destroy ( pthread_mutexattr_t * attr ) ; int pthread_mutexattr_setpshared ( pthread_mutexattr_t * attr , int pshared ) ; pshared : PTHREAD_PROCESS_PRIVATE:线程锁 PTHREAD_PROCESS_SHARED:进程锁 示例代码: /* 互斥量 实现 多进程 之间的同步 */ # include <unistd.h> # include <sys/mman.h> # include <pthread.h> # include <sys/types.h> # include <sys/wait.h> # include <fcntl.h> # include <string.h> # include <stdlib.h> # include <stdio.h> struct mt { int num ; pthread

Linux线程(六)

邮差的信 提交于 2020-01-14 23:36:02
Linux线程(六) 一、线程池: 1.线程池: 线程池是一种使用模式。线程过多会带来调度开销,进而影响缓存的局部性和整体性能。而线程池维护着多个线程,等待监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建和销毁线程的代价。线程池内部不仅能够保证内核的充分利用,还能防止过度调度。可线程的数量应该取决于可用的并发处理器、处理器内核、内存、网络socket等的数量 2.应用场景: 需要大量的线程来完成任务,且完成任务的时间比较短。Web服务器完成网页请求这样的任,非常适合使用线程池来完成。因为单个任务小,而任务量巨大。想象一下热门网站的点击次数和速度。但相对于长时间的任务。比如一个Telnet链接。线程池的优点就不明显了,因为Telnet会话时间比线程创建时间大多了 对性能要求比较苛刻的应用。比如服务器同一时刻要快速响应大量客户的请求 接受突发性的大量请求,但不至于使服务器因此产生大量的线程应用。突发性大量客户请求,在没有线程池的情况下,将产生大量线程,虽然理论上大部分操作系统线程数量数目最大值不是问题,但是短时间内产生大量线程可能使内存达到极限出现错误 3.线程池种类: 任务队列控制的线程池模型, 工作线程控制的线程池模型, 主控线程控制的线程池模型 4.线程池事例: 创建固定数量的线程池,循环从任务队列中获取任务对象 获取到任务对象后,执行任务对象的任务接口