pthread

多线程之线程的基本控制

℡╲_俬逩灬. 提交于 2020-01-14 20:30:16
一,掌握线程的终止方式,线程的连接,退出操作,清理操作。 二,线程的清理操作是如何进行的? 【注】查看标准函数库的定义解释命令,如:man 3 exit 1,线程终止 1)exit是危险的: 若进程中任意一个线程调用了exit(),_Exit(),_exit(),那么整个进程就会终止。 2)不终止进程的退出方式: 3)例子1;验证几种退出方式 建立文件test_several_exits.c;在main函数调用sleep,睡眠2秒确保子线程先运行完,再运行主线程main;内容如下: #include"unistd.h" #include"sys/types.h" #include"pthread.h" #include"stdlib.h" #include"string.h" void *pthread_fun(void *arg) { if(strcmp(arg,"1")==0) { printf("new return by return\n"); return (void*)1; } if(strcmp(arg,"2")==0) { printf("new return by pthread_exit\n"); pthread_exit( (void*)2); } if(strcmp(arg,"3")==0) { printf("new return by exit\n");

多线程控制&多线程安全&死锁&读写锁

烈酒焚心 提交于 2020-01-14 18:14:18
文章目录 多线程概念 线程控制 线程创建 线程终止 线程等待 线程分离 线程安全 如何实现线程安全? 同步 互斥 死锁 读者写者模型--读写锁 多线程概念 在传统操作系统上pcb是一个进程,描述一个程序的运行,还有一个tcp描述实现线程,但是 在linux下使用pcb描述实现了程序调度并且这些pcb共用同一个虚拟地址空间,相较于传统的pcb更加轻量化一点,因此也把linux下的pcb称之为轻量级进程。 进程是系统资源分配的基本单位。 线程是CPU调度的基本单位。 线程间的独有与共享: 独有:栈,寄存器,信号屏蔽字,errno,标识符 共享:虚拟地址空间(代码段,数据段),文件描述表,信号处理方式,工作路径,用户ID,组ID 多进程/多线程进行多任务处理(优缺点): 多线程:线程间通信更加方便灵活(全局变量,函数传参) 线程的创建/销毁成本更低 线程间的调度成本更低 异常和某个系统调用针对的是整个进程。 多进程:具有独立性,因此更加稳定,健壮。 例如:对主功能程序安全性稳定性要求更高的最好使用多进程(shell/服务器),剩下的使用多线程 共同优点 : CPU密集型程序/IO密集型程序 并行压缩CPU处理/并行压缩IO等待时间 在CPU资源足够的情况下,可以使程序的性能更高 线程控制 线程控制的接口都是库函数(操作系统并没有向用户提供创建一个轻量级进程的接口

C/C++ 线程销毁问题

自闭症网瘾萝莉.ら 提交于 2020-01-14 14:35:51
C/C++使用pthread_create创建线程后需要销毁,不销毁会导致内存泄露。 使用pthread_join销毁。因要等待线程执行完所以会导致主线程阻塞。 使用pthread_detach(pthread_self()),在线程执行完后会自动销毁。注意在线程执行函数要能退出。 两者同时使用时会导致pthread_join不再阻塞。 来源: CSDN 作者: lxfdmwin 链接: https://blog.csdn.net/qq_32761243/article/details/103970967

c++ 线程局部变量thread_local

僤鯓⒐⒋嵵緔 提交于 2020-01-14 10:53:13
Linux 中的线程局部存储(一)   本章节转自: https://blog.csdn.net/cywosp/article/details/26469435   在Linux系统中使用C/C++进行多线程编程时,我们遇到最多的就是对同一变量的多线程读写问题,大多情况下遇到这类问题都是通过锁机制来处理,但这对程序的性能带来了很大的影响,当然对于那些系统原生支持原子操作的数据类型来说,我们可以使用原子操作来处理,这能对程序的性能会得到一定的提高。   那么对于那些系统不支持原子操作的自定义数据类型,在不使用锁的情况下如何做到线程安全呢?本文将从线程局部存储方面,简单讲解处理这一类线程安全问题的方法。 一、数据类型   在C/C++程序中常存在全局变量、函数内定义的静态变量以及局部变量,对于局部变量来说,其不存在线程安全问题,因此不在本文讨论的范围之内。全局变量和函数内定义的静态变量,是同一进程中各个线程都可以访问的共享变量,因此它们存在多线程读写问题。   在一个线程中修改了变量中的内容,其他线程都能感知并且能读取已更改过的内容,这对数据交换来说是非常快捷的,但是由于多线程的存在,对于同一个变量可能存在两个或两个以上的线程同时修改变量所在的内存内容,同时又存在多个线程在变量在修改的时去读取该内存值,如果没有使用相应的同步机制来保护该内存的话,那么所读取到的数据将是不可预知的

线程认识

落爺英雄遲暮 提交于 2020-01-14 08:37:30
线程是为了让程序更好的利用cpu资源,在并行/并发处理下比进程切换cpu使用所要的花销要小。 在一个程序里的一个执行路线就叫做线程(thread)。更准确的定义是:线程是“一个进程内部的控制序列”。一切进程至少都有一个执行线程。线程在进程内部运行,本质是在进程地址空间内运行。在Linux系统中,在CPU眼中,看到的PCB都要比传统的进程更加轻量化( Linux中可以称为轻量级进程(LWP) )。透过进程虚拟地址空间,可以看到进程的大部分资源,将进程资源合理分配给每个执行流,就形成了线程执行流。 结合生活中的例子,创建一个进程就相当于工厂新建了一个厂子, 而创建一个线程就相当于在原厂的基础上增加一条生产线 ,在这方面也能看出创建新进程会分配新的虚拟地址空间,而 创建新的线程则会共用原来的虚拟地址空间(创建进程会拷贝原有的PCB并指向原有的虚拟地址空间) 。那么进程和线程的区别是什么呢?进程的作用更多是资源的管理(管理内存、文件),而 线程的作用更多是负责资源的调度和执行(也是抢占式的调度)。 ------>线程之间共用虚拟地址空间和文件描述符表 ------>线程之间不共用的资源:①栈(函数调用栈、局部变量),每个线程的栈是不共用的但不是私有的,别的线程也可以用②上下文信息(cpu中寄存器数据保存在内存中,方便下次执行)③errno错误码

线程认识

我的未来我决定 提交于 2020-01-14 08:37:20
线程是为了让程序更好的利用cpu资源,在并行/并发处理下比进程切换cpu使用所要的花销要小。 在一个程序里的一个执行路线就叫做线程(thread)。更准确的定义是:线程是“一个进程内部的控制序列”。一切进程至少都有一个执行线程。线程在进程内部运行,本质是在进程地址空间内运行。在Linux系统中,在CPU眼中,看到的PCB都要比传统的进程更加轻量化( Linux中可以称为轻量级进程(LWP) )。透过进程虚拟地址空间,可以看到进程的大部分资源,将进程资源合理分配给每个执行流,就形成了线程执行流。 结合生活中的例子,创建一个进程就相当于工厂新建了一个厂子, 而创建一个线程就相当于在原厂的基础上增加一条生产线 ,在这方面也能看出创建新进程会分配新的虚拟地址空间,而 创建新的线程则会共用原来的虚拟地址空间(创建进程会拷贝原有的PCB并指向原有的虚拟地址空间) 。那么进程和线程的区别是什么呢?进程的作用更多是资源的管理(管理内存、文件),而 线程的作用更多是负责资源的调度和执行(也是抢占式的调度)。 ------>线程之间共用虚拟地址空间和文件描述符表 ------>线程之间不共用的资源:①栈(函数调用栈、局部变量),每个线程的栈是不共用的但不是私有的,别的线程也可以用②上下文信息(cpu中寄存器数据保存在内存中,方便下次执行)③errno错误码

线程池-条件变量

北战南征 提交于 2020-01-14 07:24:55
main.c #include "jobBase.h" #include "job.h" #include "myThreadPool.h" #include <stdio.h> #include <pthread.h> #include <unistd.h> using namespace std; using namespace ThreadPool; using namespace MyJob; int main() { printf("main thread %lu\n", pthread_self()); char* threadPoolName = "xinxin's myThreadPool"; myThreadPool myFirstThreadPool(2, threadPoolName); int i = 1; for (;; ++i) { char jobName = 'a' + i; IMyJob* job = new Job(&jobName, i); if (NULL != job) { myFirstThreadPool.addJob(job); sleep(4); } else { printf("%d job is NULL\n", i); } } printf("get pending job num %d\n",

APUE:第十一章——线程

谁说胖子不能爱 提交于 2020-01-13 13:21:41
11.2 概念 11.3 线程标识 进程ID使用pid_t标识,线程ID使用pthread_t表示。 进程ID在整个系统中是唯一的,线程ID只在其所属的进程中有效。 线程ID用pthread_t数据类型表示,实现的时候可以使用结构体实现,也可以使用无符号长整型表示。 通过函数pthread_equal函数可以比较两个线程ID是否相同。 # include <pthread.h> int pthread_equal ( pthread_t tid1 , pthread_t tid2 ) ; //相同则返回非0值,不同则返回0 线程可以调用 pthread_t pthread_self(void); 获得自身的线程ID。 # include <pthread.h> pthread_t pthread_self ( void ) ; 11.4 线程创建 # include <pthread.h> int pthread_create ( pthread_t * restrict tidp , const pthread_attr_t * restrict attr , void * ( * start_rtn ) ( void ) , void * restrict arg ) ; //成功返回0,失败返回错误编号 tidp指向创建出的线程的ID; attr用于设置线程的属性;

最简单的线程池

心不动则不痛 提交于 2020-01-12 18:24:24
=================== thread_pool.h =============================== #ifndef THREAD_POOL_H__ #define THREAD_POOL_H__ #include <pthread.h> /* 要执行的任务链表 */ typedef struct tpool_work { void* (*routine)(void*); /* 任务函数 */ void *arg; /* 传入任务函数的参数 */ struct tpool_work *next; }tpool_work_t; typedef struct tpool { int shutdown; /* 线程池是否销毁 */ int max_thr_num; /* 最大线程数 */ pthread_t *thr_id; /* 线程ID数组 */ tpool_work_t *queue_head; /* 线程链表 */ pthread_mutex_t queue_lock; pthread_cond_t queue_ready; }tpool_t; /* * @brief 创建线程池 * @param max_thr_num 最大线程数 * @return 0: 成功 其他: 失败 */ int tpool_create(int max_thr_num)

Linux线程(三)

假装没事ソ 提交于 2020-01-11 23:48:26
Linux线程(三) 一、互斥量 根据前面的分析,得到的结果不是我们想要的原因是–ticket操作不是原子操作,这个共享资源可能并发的切换大其他线程,导致有多个线程同时影响到这个共享资源,所以导致得到的结果不对。 1.解决方法(加锁—>Linux中叫这把锁为互斥量): 代码必须有互斥行为:当有一个执行流(有一个线程)进入临界区时,不允许其他线程进入该临界区 如果多个线程同时要求执行临界区的代码,并且临界区内没有线程在执行,那么只允许一个线程进入该临界区 如果线程不在临界区内执行,那么该线程不能阻止其他线程进入临界区 二、.互斥量的接口: 1.初始化互斥量 方法一:静态分配 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER 方法二:动态分配 int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr); 功能:初始化互斥量 参数:pthread_mutex_t *restrict mutex:要初始化的互斥量 const pthread_mutexattr_t *restrict attr:指定了新建互斥锁的属性。如果参数attr为NULL,则使用默认的互斥锁属性,默认属性为快速互斥锁 返回值