自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

胖佳儿Clara的博客

每天进步一点点~

  • 博客(30)
  • 资源 (2)
  • 收藏
  • 关注

原创 【java】如何实现秒杀功能

秒杀的过程中【减库存,下订单,写入秒杀订单】需要具有原子性。所以要保证这三个操作是一个事物。在java中可以用@Transactional注释//保证这三个操作,减库存 下订单 写入秒杀订单是一个事物 @Transactional public OrderInfo seckill(User user, GoodsVo goods){ //减库存 goodsService.reduceStock(goods); //下订单 写入秒杀订单

2020-08-23 02:37:20 1487

原创 【Java】自动登录

本来想通过Oauth2.0来实现自动登录的。但是因为一系列原因,最后还是通过如下的方法。自定义SpringMVC参数解析器, 改变SpringMVC的Controller传入参数,实现可以User替换Token做为参数从登陆页面传到商品列表页面WebConfig.java/** * 自定参数解析器, 作用:改变SpringMVC的Controller传入参数,实现可以User替换Token做为参数从登陆页面传到商品列表页面 */@Configurationpublic class Web

2020-08-23 02:36:40 223

原创 【Java】RedisTemplate

//向redis里存入数据和设置缓存时间 stringRedisTemplate.opsForValue().set("baike", "100", 60 * 10, TimeUnit.SECONDS);//val做-1操作 stringRedisTemplate.boundValueOps("baike").increment(-1);//根据key获取缓存中的val stringRedisTemplate.opsForValue().get("baike")//val +1 str

2020-08-23 02:33:46 546

原创 【Java】压力测试

打开JMeter,对商品列表和获取用户信息进行压力测试。对Redis进程压力测试

2020-08-23 02:32:46 462

原创 【Java】RabbitMQ

helloworld模式动态路由模式

2020-08-23 02:31:21 122

原创 【HTTP】HTTP解析

首先我们来看一下HTTP报文的结构解析请求行int process_status_line(char *start, char *end, struct http_request *httpRequest) { int size = end - start; //method char *space = strstr(start," "); assert(space != NULL); int method_size = space - start; httpRequest->met

2020-08-10 17:19:59 152

原创 【python】基于 Diffie-Hellman 的三方密钥交换算法演示

DH-demo基于 Diffie-Hellman 的三方密钥交换算法演示代码:https://github.com/Clara998/DH-demo实验环境:方法1:为了统一依赖,我们采用 Pyenv 来管理 Python 的版本,Pipenv 来管理依赖的版本。Windows 10 下安装 PyenvPipenv 的安装简明操作指南方法2:实验环境为python3.7及django3.0.6,可以自行下载算法流程:随机生成大素数p生成大素数p的一个原根gAlice,Bob,C

2020-08-10 15:17:14 1911 1

原创 【网络编程】线程池并发服务器

线程池思路threadpool_t结构体struct threadpool_t { pthread_mutex_t lock; pthread_mutex_t thread_counter; //busy_thread_num修改时加解锁 pthread_cond_t queue_not_full; pthread_cond_t queue_not_empty; pthread_t *thread; //线程数组 pthread_t adjust_t

2020-05-13 18:13:04 305

原创 【linux】线程同步

互斥锁主要应用函数pthread_mutex_init静态初始化:如果互斥锁 mutex 是静态分配的(定义在全局,或加了static关键字修饰),可以直接使用宏进行初始化。 pthead_mutex_t muetx = PTHREAD_MUTEX_INITIALIZER;动态初始化:局部变量应采用动态初始化。pthread_mutex_init(&mutex, NULL)pthread_mutex_lock函数加锁。可理解为将mutex–(或-1)int pth

2020-05-09 22:17:29 141

原创 【Linux】线程

概述相当于一个正在运行的函数线程有独立的PCB,但是多个线程共享内存最小执行单位。而进程是最小的分配资源单位创建线程相关API作用:对应进程中fork() 函数。int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);...

2020-05-08 20:47:14 143

原创 【网络编程】多路I/O转接服务器之epoll

最近学习网络编程相关,学习资源在b站搜索【linux网络编程】。本文章记录相关学习心得。相关API创建一个epoll句柄,参数size用来告诉内核监听的文件描述符的个数,跟内存大小有关。此步骤创建一个建议大小为size的红黑树(二叉平衡树),返回值为根结点的fd #include <sys/epoll.h> int epoll_create(int size) si...

2020-04-28 21:44:25 188 1

原创 【网络编程】多路I/O转接服务器之poll

最近学习网络编程相关,学习资源在b站搜索【linux网络编程】。本文章记录相关学习心得。主要结构#include <poll.h>int poll(struct pollfd *fds, nfds_t nfds, int timeout); struct pollfd { int fd; /* 文件描述符 */ short events; ...

2020-04-28 19:54:17 239 2

原创 【网络编程】多路I/O转接服务器之select

·

2020-04-27 19:45:29 176

原创 【网络编程】实现一个简单的多进程并发服务器

最近学习网络编程相关,学习资源在b站搜索【linux网络编程】。本文章记录相关学习心得。Socket发送端和接收端成对出现绑定ip + portsocket为linux中的伪文件一个文件描述符有2个缓冲区,一读一写sockaddr_in 结构体struct sockaddr_in { __kernel_sa_family_t sin_family; /*...

2020-04-20 01:38:56 568 4

原创 【面经】微软SWE暑期实习

题目7个晶体管上的灯的亮暗可以组成0-9的任意一个数字。假设有n组晶体管,每组晶体管中至少有一个亮,可能存在坏了的晶体管。假设有2组晶体管,第一组是数字2,因为有坏了的可能,2->2,2->8;其可能为2/8;第2组是数字4,其可能为3/8/9由此可以组成{23,28,29,83,88,89}input:n个7位数,即有n组晶体管output:组成的数字,例如本...

2020-04-14 17:47:04 872

原创 【编译原理】实现一个计算器

实现一个计算器,包括加减,乘除,括号,错误提示,id等,相当于一个小型的解释器。其中重要的思想是把字符转换成token 递归解析//编译原理实现计算器#include<bits/stdc++.h>using namespace std;//int factor(const char **) throw();enum { //枚举:第一个元素=0,第二个就为1,依...

2020-04-14 17:25:05 1623

原创 【汇编】用户登录验证程序

程序执行后,给出操作提示,请用户输入用户名和密码;用户在输入密码时,程序不回显输入字符;只有当用户输入的用户名、密码字符串和程序内定的字符串相同时,才显示欢迎界面,并返回DOS。界面的颜色自定(彩色或黑白)实验代码:;FILENAME: EXA131.ASM.486NEWLINE MACRO ;换行;宏指令 MACRO...ENDM ...

2019-10-16 14:21:43 3520 2

原创 【汇编】统计该串字符中的ASCII码在42H~45H之间的字符个数

从BUF单元开始存有一字符串(长度<255),编程实现统计该串字符中的ASCII码在42H~45H之间的字符个数,并将统计结果以二进制形式显示在屏幕上。;FILENAME: EXA131.ASM.486DATA SEGMENT USE16BUF DB 'BB' ;开始存有一字符串COUNT EQU $-BUF ;count...

2019-10-06 03:00:05 5572 1

原创 【汇编】显示:25+9=34

1.题目要求下面给出的是一个通过比较法完成8位二进制数转换成十进制数送屏幕显示功能的汇编语言源程序,但有很多语法错误。要求实验者按照原样对源程序进行编辑,汇编后,根据TASM给出的错误信息对源程序进行修改,直到没有语法错误为止。然后进行链接,并执行相应的可执行文件。正确的执行结果是在屏幕上显示:25+9=34。2.流程图3.程序;FILENAME: EXA131.ASM...

2019-10-05 21:54:29 2406 1

原创 【Jarvis OJ】Login--password='".md5($pass,true)."'

Login题目需要密码才能获得flag哦。题目链接:http://web.jarvisoj.com:32772思路:打开链接是一个提交password界面,放到burp里看一看呀~ 看到有提示哦~Hint: "select * from `admin` where password='".md5($pass,true)."'"一看到md5,我就想到pas...

2018-10-31 20:45:20 1587 1

原创 【Linux】重定向

参考资料:1.视频课程《Linux运维》2.书籍PDF版《Linux运维 Web集群实战》3.https://ryanstutorials.net/linuxtutorial/piping.php4.学习笔记保存在幕布:这里有完整Linux学习笔记哦~重定向管道和重定向的作用是保持数据在程序和文件之间流动。比如说:通常情况下,我们会在屏幕上显示输出,这在大多数情况下很方便,但有...

2018-10-27 22:40:57 200

原创 【Linux】特殊字符

参考资料:1.视频课程《Linux运维》2.书籍PDF版《Linux运维 Web集群实战》学习笔记保存在幕布:这里有完整Linux学习笔记哦~  特殊字符【|】管道 例子:ifconfig|sed -n '2p',【|】即使把ifconfig的输出当成是后面的输入,sed -n取消默认输出,2为第二行,p为打印出来 【..】或【../】上一级目录 【.】或【./】当...

2018-10-27 22:39:41 309

原创 【Linux】常用快捷键

参考资料:1.视频课程《Linux运维》2.书籍PDF版《Linux运维 Web集群实战》学习笔记保存在幕布:这里有完整Linux学习笔记哦~ 常用快捷键 http://oldboy.blog.51cto.com/2561410/907098【Tab】命令补全,路径补全。按三下是所有可能 【Ctrl+c】命令终止 【Ctrl+d】退出当前窗口,相当于exit,logou...

2018-10-27 22:38:04 202

原创 【Linux】Linux目录

参考资料:1.视频课程《Linux运维》2.书籍PDF版《Linux运维 Web集群实战》3.学习笔记保存在幕布:这里有完整Linux学习笔记哦~ Linux目录特点 /是所有目录的顶点 目录结构像一棵倒挂的树 目录和磁盘分区是没有关联的, /下不同的目录可能会对应不同的分区或磁盘 所有目录按照一定类别有规律组织 分类 /usr/bin 可执行文件...

2018-10-27 22:36:16 1310

原创 【Linux】Linux系统的基础优化讲解

参考资料:1.视频课程《Linux运维》2.书籍PDF版《Linux运维 Web集群实战》学习笔记保存在幕布:这里有完整Linux学习笔记哦~Linux系统的基础优化讲解1.关闭SELinux(类似防火墙的安全机制,安全用别的方案解决) 方法1:vim修改 vim /etc/selinux/config (使SELINUX=disabled,彻底关掉) 方法2:...

2018-10-27 22:34:17 331

原创 【Linux】远程连接Linux系统及故障排查

参考资料:1.视频课程《Linux运维》2.书籍PDF版《Linux运维 Web集群实战》远程连接Linux系统原理 互联网上的计算机都会有一个32位的地址,ip地址。 我们访问服务器,就必须通过这个ip地址。 局域网里也有预留的ip地址 192/10/172开头。局域网的ip地址也是唯一的。 NAT模式,电脑宿主机的ip在局域网里一定唯一,NAT模式创建虚拟机,虚拟机就...

2018-10-21 01:18:49 283

原创 【Linux】路径,mkdir,touch,vi等知识知识问答精讲

参考资料:1.视频课程《Linux运维》2.书籍PDF版《Linux运维 Web集群实战》路径,mkdir,touch,vi等知识知识问答精讲Linux 系统命令操作语法的格式 命令 [参数选项] [文件或路径] 其中[]表示是非必须的,多个参数可以连在一起写 创建一个目录/data windows下的路径:c:\data\test linux下的路径:/data/...

2018-09-29 18:39:58 513

原创 【Linux】学习环境搭建,ip配置及ssh连接

参考资料:1.视频课程《Linux运维》2.书籍PDF版《Linux运维 Web集群实战》学习笔记保存在幕布:这里有完整Linux学习笔记哦~ 搭建学习环境 VMware Workstation 12 装双系统不是工作环境 安装 CentOS虚拟机 下载镜像 新建虚拟机,选择磁盘10G,2网卡,NAT模式 Operating System not fo...

2018-09-29 18:25:45 285

原创 【Linux】操作系统

参考资料:1.视频课程《Linux运维》2.书籍PDF版《Linux运维 Web集群实战》 什么是操作系统? Operating System, 简称OS,是计算机系统中必不可少的基础系统软件。是处于用户与计算机系统硬件之间用于传递信息的系统程序软件。 目前PC(Intel x86)上常见的操作系统:Windows,Linux,DOS,Unix 什么是Linux? ...

2018-09-28 23:01:38 212

原创 【Linux】计算机硬件基础

参考资料:1.视频课程《Linux运维》2.书籍PDF版《Linux运维 Web集群实战》3微信公众号文章《高并发那点事儿》学习笔记保存在幕布:这里有完整Linux学习笔记哦~一、网站PC服务器1U(Unit)=4.45cm 2U型号(2014-2016):R720,R730 1U型号(2014-2016):R420,R430,R620,R630 互联网公司服务器品牌:...

2018-09-26 21:33:10 318 3

Linux系统编程之线程同步

同步概念 所谓同步,即同时起步,协调一致。不同的对象,对“同步”的理解方式略有不同。如,设备同步,是指在两个设备之间规定一个共同的时间参考;数据库同步,是指让两个或多个数据库内容保持一致,或者按需要部分保持一致;文件同步,是指让两个或多个文件夹里的文件保持一致。等等 而,编程中、通信中所说的同步与生活中大家印象中的同步概念略有差异。“同”字应是指协同、协助、互相配合。主旨在协同步调,按预定的先后次序运行。 线程同步 同步即协同步调,按预定的先后次序运行。 线程同步,指一个线程发出某一功能调用时,在没有得到结果之前,该调用不返回。同时其它线程为保证数据一致性,不能调用该功能。 举例1: 银行存款 5000。柜台,折:取3000;提款机,卡:取 3000。剩余:2000 举例2: 内存中100字节,线程T1欲填入全1, 线程T2欲填入全0。但如果T1执行了50个字节失去cpu,T2执行,会将T1写过的内容覆盖。当T1再次获得cpu继续 从失去cpu的位置向后写入1,当执行结束,内存中的100字节,既不是全1,也不是全0。 产生的现象叫做“与时间有关的错误”(time related)。为了避免这种数据混乱,线程需要同步。 “同步”的目的,是为了避免数据混乱,解决与时间有关的错误。实际上,不仅线程间需要同步,进程间、信号间等等都需要同步机制。 因此,所有“多个控制流,共同操作一个共享资源”的情况,都需要同步。 数据混乱原因: 1. 资源共享(独享资源则不会) 2. 调度随机(意味着数据访问会出现竞争) 3. 线程间缺乏必要的同步机制。 以上3点中,前两点不能改变,欲提高效率,传递数据,资源必须共享。只要共享资源,就一定会出现竞争。只要存在竞争关系,数据就很容易出现混乱。 所以只能从第三点着手解决。使多个线程在访问共享资源的时候,出现互斥。 互斥量mutex Linux中提供一把互斥锁mutex(也称之为互斥量)。 每个线程在对资源操作前都尝试先加锁,成功加锁才能操作,操作结束解锁。 资源还是共享的,线程间也还是竞争的, 但通过“锁”就将资源的访问变成互斥操作,而后与时间有关的错误也不会再产生了。 但,应注意:同一时刻,只能有一个线程持有该锁。 当A线程对某个全局变量加锁访问,B在访问前尝试加锁,拿不到锁,B阻塞。C线程不去加锁,而直接访问该全局变量,依然能够访问,但会出现数据混乱。 所以,互斥锁实质上是操作系统提供的一把“建议锁”(又称“协同锁”),建议程序中有多线程访问共享资源的时候使用该机制。但,并没有强制限定。 因此,即使有了mutex,如果有线程不按规则来访问数据,依然会造成数据混乱。 主要应用函数: pthread_mutex_init函数 pthread_mutex_destroy函数 pthread_mutex_lock函数 pthread_mutex_trylock函数 pthread_mutex_unlock函数 以上5个函数的返回值都是:成功返回0, 失败返回错误号。 pthread_mutex_t 类型,其本质是一个结构体。为简化理解,应用时可忽略其实现细节,简单当成整数看待。 pthread_mutex_t mutex; 变量mutex只有两种取值1、0。 pthread_mutex_init函数 初始化一个互斥锁(互斥量) ---> 初值可看作1 int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr); 参1:传出参数,调用时应传 &mutex restrict关键字:只用于限制指针,告诉编译器,所有修改该指针指向内存中内容的操作,只能通过本指针完成。不能通过除本指针以外的其他变量或指针修改 参2:互斥量属性。是一个传入参数,通常传NULL,选用默认属性(线程间共享)。 参APUE.12.4同步属性 1. 静态初始化:如果互斥锁 mutex 是静态分配的(定义在全局,或加了static关键字修饰),可以直接使用宏进行初始化。e.g. pthead_mutex_t muetx = PTHREAD_MUTEX_INITIALIZER; 2. 动态初始化:局部变量应采用动态初始化。e.g. pthread_mutex_init(&mutex, NULL) pthread_mutex_destroy函数 销毁一个互斥锁 int pthread_mutex_destroy(pthread_mutex_t *mutex); pthread_mutex_lock函数 加锁。可理解为将mutex--(或-1) int pthread_mutex_lock(pthread_mutex_t *mutex); pthread_mutex_unlock函数 解锁。可理解为将mutex ++(或+1) int pthread_mutex_unlock(pthread_mutex_t *mutex); pthread_mutex_trylock函数 尝试加锁 int pthread_mutex_trylock(pthread_mutex_t *mutex); 加锁与解锁 lock与unlock: lock尝试加锁,如果加锁不成功,线程阻塞,阻塞到持有该互斥量的其他线程解锁为止。 unlock主动解锁函数,同时将阻塞在该锁上的所有线程全部唤醒,至于哪个线程先被唤醒,取决于优先级、调度。默认:先阻塞、先唤醒。 例如:T1 T2 T3 T4 使用一把mutex锁。T1加锁成功,其他线程均阻塞,直至T1解锁。T1解锁后,T2 T3 T4均被唤醒,并自动再次尝试加锁。 可假想mutex锁 init成功初值为1。 lock 功能是将mutex--。 unlock将mutex++ lock与trylock: lock加锁失败会阻塞,等待锁释放。 trylock加锁失败直接返回错误号(如:EBUSY),不阻塞。 加锁步骤测试: 看如下程序:该程序是非常典型的,由于共享、竞争而没有加任何同步机制,导致产生于时间有关的错误,造成数据混乱: #include #include #include void *tfn(void *arg) { srand(time(NULL)); while (1) { printf("hello "); sleep(rand() % 3); /*模拟长时间操作共享资源,导致cpu易主,产生与时间有关的错误*/ printf("world\n"); sleep(rand() % 3); } return NULL; } int main(void) { pthread_t tid; srand(time(NULL)); pthread_create(&tid, NULL, tfn, NULL); while (1) { printf("HELLO "); sleep(rand() % 3); printf("WORLD\n"); sleep(rand() % 3); } pthread_join(tid, NULL); return 0; } 【mutex.c】 【练习】:修改该程序,使用mutex互斥锁进行同步。 1. 定义全局互斥量,初始化init(&m, NULL)互斥量,添加对应的destry 2. 两个线程while中,两次printf前后,分别加lock和unlock 3. 将unlock挪至第二个sleep后,发现交替现象很难出现。 线程在操作完共享资源后本应该立即解锁,但修改后,线程抱着锁睡眠。睡醒解锁后又立即加锁,这两个库函数本身不会阻塞。 所以在这两行代码之间失去cpu的概率很小。因此,另外一个线程很难得到加锁的机会。 4. main 中加flag = 5 将flg在while中-- 这时,主线程输出5次后试图销毁锁,但子线程未将锁释放,无法完成。 5. main 中加pthread_cancel()将子线程取消。 【pthrd_mutex.c】 结论: 在访问共享资源前加锁,访问结束后立即解锁。锁的“粒度”应越小越好。 死锁 1. 线程试图对同一个互斥量A加锁两次。 2. 线程1拥有A锁,请求获得B锁;线程2拥有B锁,请求获得A锁 【作业】:编写程序,实现上述两种死锁现象。 读写锁 与互斥量类似,但读写锁允许更高的并行性。其特性为:写独占,读共享。 读写锁状态: 一把读写锁具备三种状态: 1. 读模式下加锁状态 (读锁) 2. 写模式下加锁状态 (写锁) 3. 不加锁状态 读写锁特性: 1. 读写锁是“写模式加锁”时, 解锁前,所有对该锁加锁的线程都会被阻塞。 2. 读写锁是“读模式加锁”时, 如果线程以读模式对其加锁会成功;如果线程以写模式加锁会阻塞。 3. 读写锁是“读模式加锁”时, 既有试图以写模式加锁的线程,也有试图以读模式加锁的线程。那么读写锁会阻塞随后的读模式锁请求。优先满足写模式锁。读锁、写锁并行阻塞,写锁优先级高 读写锁也叫共享-独占锁。当读写锁以读模式锁住时,它是以共享模式锁住的;当它以写模式锁住时,它是以独占模式锁住的。写独占、读共享。 读写锁非常适合于对数据结构读的次数远大于写的情况。 主要应用函数: pthread_rwlock_init函数 pthread_rwlock_destroy函数 pthread_rwlock_rdlock函数 pthread_rwlock_wrlock函数 pthread_rwlock_tryrdlock函数 pthread_rwlock_trywrlock函数 pthread_rwlock_unlock函数 以上7 个函数的返回值都是:成功返回0, 失败直接返回错误号。 pthread_rwlock_t类型 用于定义一个读写锁变量。 pthread_rwlock_t rwlock; pthread_rwlock_init函数 初始化一把读写锁 int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr); 参2:attr表读写锁属性,通常使用默认属性,传NULL即可。 pthread_rwlock_destroy函数 销毁一把读写锁 int pthread_rwlock_destroy(pthread_rwlock_t *rwlock); pthread_rwlock_rdlock函数 以读方式请求读写锁。(常简称为:请求读锁) int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock); pthread_rwlock_wrlock函数 以写方式请求读写锁。(常简称为:请求写锁) int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock); pthread_rwlock_unlock函数 解锁 int pthread_rwlock_unlock(pthread_rwlock_t *rwlock); pthread_rwlock_tryrdlock函数 非阻塞以读方式请求读写锁(非阻塞请求读锁) int pthread_

2020-05-08

linux系统编程之线程.zip

线程概念 什么是线程 LWP:light weight process 轻量级的进程,本质仍是进程(在Linux环境下) 进程:独立地址空间,拥有PCB 线程:也有PCB,但没有独立的地址空间(共享) 区别:在于是否共享地址空间。 独居(进程);合租(线程)。 Linux下: 线程:最小的执行单位 进程:最小分配资源单位,可看成是只有一个线程的进程。 Linux内核线程实现原理 类Unix系统中,早期是没有“线程”概念的,80年代才引入,借助进程机制实现出了线程的概念。因此在这类系统中,进程和线程关系密切。 1. 轻量级进程(light-weight process),也有PCB,创建线程使用的底层函数和进程一样,都是clone 2. 从内核里看进程和线程是一样的,都有各自不同的PCB,但是PCB中指向内存资源的三级页表是相同的 3. 进程可以蜕变成线程 4. 线程可看做寄存器和栈的集合 5. 在linux下,线程最是小的执行单位;进程是最小的分配资源单位 察看LWP号:ps –Lf pid 查看指定线程的lwp号。 三级映射:进程PCB --> 页目录(可看成数组,首地址位于PCB中) --> 页表 --> 物理页面 --> 内存单元 参考:《Linux内核源代码情景分析》 ----毛德操 对于进程来说,相同的地址(同一个虚拟地址)在不同的进程中,反复使用而不冲突。原因是他们虽虚拟址一样,但,页目录、页表、物理页面各不相同。相同的虚拟址,映射到不同的物理页面内存单元,最终访问不同的物理页面。 但!线程不同!两个线程具有各自独立的PCB,但共享同一个页目录,也就共享同一个页表和物理页面。所以两个PCB共享一个地址空间。 实际上,无论是创建进程的fork,还是创建线程的pthread_create,底层实现都是调用同一个内核函数clone。 如果复制对方的地址空间,那么就产出一个“进程”;如果共享对方的地址空间,就产生一个“线程”。 因此:Linux内核是不区分进程和线程的。只在用户层面上进行区分。所以,线程所有操作函数 pthread_* 是库函数,而非系统调用。 线程共享资源 1.文件描述符表 2.每种信号的处理方式 3.当前工作目录 4.用户ID和组ID 5.内存地址空间 (.text/.data/.bss/heap/共享库) 线程非共享资源 1.线程id 2.处理器现场和栈指针(内核栈) 3.独立的栈空间(用户空间栈) 4.errno变量 5.信号屏蔽字 6.调度优先级 线程优、缺点 优点: 1. 提高程序并发性 2. 开销小 3. 数据通信、共享数据方便 缺点: 1. 库函数,不稳定 2. 调试、编写困难、gdb不支持 3. 对信号支持不好 优点相对突出,缺点均不是硬伤。Linux下由于实现方法导致进程、线程差别不是很大。 线程控制原语 pthread_self函数 获取线程ID。其作用对应进程中 getpid() 函数。 pthread_t pthread_self(void); 返回值:成功:0; 失败:无! 线程ID:pthread_t类型,本质:在Linux下为无符号整数(%lu),其他系统中可能是结构体实现 线程ID是进程内部,识别标志。(两个进程间,线程ID允许相同) 注意:不应使用全局变量 pthread_t tid,在子线程中通过pthread_create传出参数来获取线程ID,而应使用pthread_self。 pthread_create函数 创建一个新线程。 其作用,对应进程中fork() 函数。 int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg); 返回值:成功:0; 失败:错误号 -----Linux环境下,所有线程特点,失败均直接返回错误号。 参数: pthread_t:当前Linux中可理解为:typedef unsigned long int pthread_t; 参数1:传出参数,保存系统为我们分配好的线程ID 参数2:通常传NULL,表示使用线程默认属性。若想使用具体属性也可以修改该参数。 参数3:函数指针,指向线程主函数(线程体),该函数运行结束,则线程结束。 参数4:线程主函数执行期间所使用的参数。 在一个线程中调用pthread_create()创建新的线程后,当前线程从pthread_create()返回继续往下执行,而新的线程所执行的代码由我们传给pthread_create的函数指针start_routine决定。star

2020-05-05

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除