自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

风清扬

大风起兮云飞扬

  • 博客(24)
  • 收藏
  • 关注

原创 LINUX内核研究----系统调用过程分析

系统调用的定义:      因为计算机中的各种资源都是由操作系统统一管理,凡是和系统资源相关的操作都必须通过操作系统来完成,例如IO操作、分配内存、文件操作等。而用户程序是没有权限直接进行这些操作的,所以必须通过某种方式来向操作系统提出服务请求。因此操作系统必须提供一套某种方式的接口,让用户通过这些接口使用操作系统提供的各项功能或者访问系统资源,操作系统给应用程序的接口就是系统调用。系统调用实现的...

2017-10-29 22:23:59 462

原创 结构体对齐规则

1. 结构体的内存布局记住两个规则即可,这是编译器的优化为了提高CPU的寻址效率的措施。规则1:结构体中第一个成员的偏移量是0,以后每个成员的位置是x的倍数;           x = min(#pragma pack(), 该成员自身的长度)规则2:成员对齐后,结构体自身也要对齐,按照y的倍数进行;          y = min(#pragm

2017-10-26 20:53:08 308

原创 指针和数组的区别

在一个项目中定义两个文件//a.cppint a[3] = { 1, 2, 3 };//b.cpp#includeextern int *a;//引用a.cpp的数组名a,但是不把它当数组而是当成指针void main(){ printf("%d\n", a); printf("%d\n", a + 1); printf("%d\n", *a); getchar();

2017-10-22 21:59:46 172

原创 i++和++i的区别和实现的原理探究

int main(){ int i = 0; i++; ++i; system("pause"); return 0;}首先看一段简单的程序,通过反汇编直接探究i++和++i的实现原理

2017-10-22 20:10:02 3621 1

原创 汇编角度看指针和引用的区别

一、定义上来看:引用是变量的别名,指针是指向变量的地址。引用不可以为空但是指针可以为空,所以引用必须在定义的时候必须初始化并且初始化后不能被改变引用的对象,但是指针可以该变自己的指向。引用必须引用有内存地址的量,如果是引用常量的话,必须使用常引用。(常引用的实现方法是编译器为常量开辟一个临时量的内存空间进行引用)对引用和指针分别用SIZEOF求大小的话,引用的结果是所指向对像的大小,但是指针则永远...

2017-10-20 16:48:51 999

原创 内联函数、普通函数、宏定义

对于一个频繁使用的短小函数,c用宏定义,c++用inline实现。一、宏定义和内联函数的区别1、宏定义只是普通的文本替换,宏定义是没有类型检查的,无论对还是错都是直接替换。所以宏替换容易出错,直接替换会产生符号的优先级的问题会一些意想不到的结果。      内联函数在编译的时候会进行类型的检查,内联函数满足函数的性质,比如有返回值、参数列表等。相对宏替换来说不仅提高了效率还

2017-10-18 16:26:05 388

原创 读写锁实现读写者问题

注意:LINUX 读写锁是写者优先锁/*producer and constmer*/#include#include#include#includepthread_rwlock_t rwlock;int good = 0;void *writer(void *argv){ while(1) { pthread_rwlock_wrlock(&rwlock); good

2017-10-18 15:00:15 483

原创 两个信号量实现生产者消费者模型

/*producer and constmer*/#include#include#include#include#includesem_t pro_sem;sem_t cus_sem;int good = 0;void *customer(void *argv){ while(1) { sem_wait(&cus_sem); good--; printf("cu

2017-10-18 14:18:25 1658

原创 互斥量和条件变量实现生产者消费者模型

/*producer and constmer*/#include#include#include#includepthread_mutex_t mutex;pthread_cond_t cond;//int good = 0;void *customer(void *argv)//消费者代码{ while(1) { pthread_mutex_lock(&mutex);

2017-10-18 14:10:29 474

原创 汇编代码分析----函数的调用堆栈过程(进程内核栈的切换过程)

当栈中保存函数调用所需要的维护信息,我们称之为堆栈帧。堆栈帧一般包括以下几个方面的内容:函数的返回地址和参数临时变量函数调用的上下文信息一个函数的堆栈帧用ebp和esp两个寄存器划定范围ebp寄存器始终指向当前函数栈帧的栈底。esp寄存器始终指向当前函数栈帧的栈顶。堆栈帧是从高地址向低地址增长的。具体的函数调用过程让我用一个简单的程序并结合画图讲解以增加自己对其过程的深入理解。int sum(in...

2017-10-15 19:48:26 1288

原创 C++中怎么使用EOF结束输入

#includeusing namespce std;void main(){ int a; while(cin >>a) { ;//循环输入的代码块 }}运行程序之后循环输入,按下CTRL + Z  并且还得按下回车,当初就是没按回车一直不知道什么意思,输入还没有停止。

2017-10-15 14:37:19 24696 1

原创 深入理解静态链接的过程

静态链接的过程各个文件之间都是单独编译的。编译生成可重定位目标文件后,目标文件格式也是ELF可执行文件格式但是并不能运行:根本原因是在编译的时候目标文件并没有分配虚拟地址原因如下:如果是定义在本文件的函数和变量编译器可以为它分配地址,但是如果当前的源文件引用其他文件的函数或者是全局变量,这个时候就无法确定其地址了。所以就把虚拟地址的确定同意推迟到链接的过程。就需要调用系统的链接器将目标文件进行链接...

2017-10-10 22:03:52 924

原创 强符号和弱符号

在编程的过程中经常会遇到一种符号重定义的情况。比如在多个目标文件中含有名字相同的全局变量的定义,那么在链接时会出现符号重定义的错误,我们将这种符号称为强符号。相对来说我们也可以定义一种叫做弱符号的概念,C/C++编译器来说默认函数和初始化了的全局变量为强符号,而未初始化的全局变量为弱符号。针对强弱符号的定义,链接器会按照下列的规则进行处理强弱符号的选择:1、  不允许强符号多次定义,如果有

2017-10-10 21:23:25 1476

原创 C/C++语言中怎么使用extern c

C++为了和C兼容,C++使用extern “C”关键字C++编译器将在extern “C”的大括号的内部的代码当做C语言编译处理,这样C++的名称修饰规则将不会起作用。主要原因是:作为一种面向对象的语言,C++支持函数重载,而过程式语言C则不支持。函数被C++编译后在符号库中的名字与C语言的不同。例如,假设某个函数的原型为:void foo( int x,int y );该函数被C编译器编译后在...

2017-10-10 20:47:46 262

原创 编程判断是C源文件还是C++源文件

C+编译器会在编译C++源程序的时候自动生成一个宏:__cplusplus  可以通过这个宏来判断是C源文件还是C++源文件代码如下#includevoid main(){#ifdef __cplusplus printf("c++");#else printf("c");#endif}

2017-10-10 20:42:59 1028

原创 进程的虚拟地址空间

进程的虚拟地址空间是独立的可执行文件生成后,我们需要知道一点:进程的虚拟地址空间是独立的,进程能够使用除了OS内核区域外的所有地址空间。这里的独立是指进程内部使用的虚拟地址和其他进程没有关系,一个进程可以使用4GB(32位OS)中除去OS内核使用的其他所有虚拟地址空间,每个进程都是这样。那么进程间是怎么来进行隔离的呢,这个可以在下一节,进程的执行过程中,简单的介绍。下面是进程地址空间的简易

2017-10-09 22:45:28 629

原创 对目标文件(可重定位文件)ELF文件结构的个人研究及理解

目标文件的格式:现在PC平台流行的可执行文件格式主要是windows下的PE(.exe)和linux(.out)下的ELF。目标文件就是源代码经过编译链接后但未进行链接的那些中间文件,也叫可重定位文件:windows下的(.obj)和linux下的(.o)文件,他们跟可执行文件的格式几乎是一样的。不光是目标文件按照可执行文件格式存储动态链接库(windows下的.dll、linux下的.so)静态...

2017-10-09 22:21:25 613

原创 线程同步之信号量

信号量头文件  semaphore.h信号量类型:sem_t  加强版的互斥锁:1、互斥锁的初始值只能是1,但是信号量可以人为的规定有几个互斥量,规定共享资源的数量。2、互斥锁规定只能一个线程进行加锁和解锁的操作,但是信号量可以让这个线程加锁,另一个线程解锁。3、 互斥量用于线程的互斥,信号线用于线程的同步。 这是互斥量和信号量的根本区别

2017-10-08 19:01:40 381

原创 进程同步之条件变量

条件变量  #include<pthread.h>特点:读写锁和互斥锁不是任何时候都能阻塞线程,只能保证一个线程访问共享资源。概念:提供了阻塞线程的一种机制,相当于把不符合条件的线程阻塞在一定的代码区域。尤其记住的是条件变量不能实现线程同步,它不是不是锁,但是可以在线程不满足条件的时候阻塞线程,不让线程继续运行。满足条件时通知线程继续运行。它的最主要作用是阻塞线程,因此还必须使用条件变...

2017-10-08 17:22:02 1263 1

原创 线程同步之读写锁

读写锁:                1、  读写锁的概念:是一把锁,是一个pthread_rwlock_t 类型的锁机制                       拥有读(读内存操作)属性和写(写内存操作)属性的锁。                2、  读写锁的特性:读共享,写独占。                       读写互斥不能同时进行:先读后写阻塞。

2017-10-08 15:07:32 216

原创 线程同步之互斥锁(互斥量)

互斥锁:#include1、互斥锁的数据类型:pthread_mutex_t2、互斥锁的特点:同步线程,控制数据的访问是同步的3、互斥锁的缺点:效率低,操作之前要加锁和解锁操作4、互斥锁的使用步骤:               创建一把锁 :pthread_mutex_t  mrtux;         初始化这把锁:pthread_mutex_init(&mutex,

2017-10-08 14:38:39 293

原创 线程同步之死锁的原因和解决方法

造成死锁的原因:1、  自己锁自己,线程获得锁A,没有给自己解锁又去拿锁A,一直阻塞造成死锁。2、  两个共享数据,两把锁。线程一获得锁 A阻塞在B锁上,但是线程二获得B锁阻塞在A锁上,两者造成死锁解决方法:1让线程按顺序访问共享资源。2在访问另外一个共享资源之前先解锁已经拥有的锁3在访问之前使用trylock函数尝试加锁,如果失败就直接返回

2017-10-07 15:33:08 1063

原创 进程间通信—信号

信号概念:信号是在软件层次上对中断机制的一种模拟,它是比较复杂的通信方式,用于通知进程有某事件发生,一个进程收到一个信号与处理器收到一个中断请求效果上可以说是一致的。进程在接收到这个信号以后,可以设置响应的处理动作:忽略或者调用函数进行处理。在linux下命令行$kill -l可以查看linux下的所有信号:一共64个信号,从1开始编号,其中也存在0号信号,但是0号信号是用来测试某

2017-10-07 15:10:07 336

原创 进程和线程联系和区别

进程和线程的区别和联系,一个经典的概念问题。作为一个程序员都应该好好的回答这个问题,提高自己对程序的抽象认识。简单的概念区分:进程:1、进程是磁盘上的可执行文件加载到内存中运行时候的状态,是一种动态的概念,进程是应用程序的运行实例。2、进程是资源分配的基本单位,以进程为单位向操作系统请求资源:虚拟地址空间、打开文件。线程:1、线程是相对于进程来说更小的一个概念:线程只是进程里的一条执行序列,基本上...

2017-10-06 21:41:26 334

空空如也

空空如也

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

TA关注的人

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