自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(23)
  • 收藏
  • 关注

原创 tlpi: 文件锁(flock(), fcntl())

文件锁文件锁是一种专为文件I/O设计的一种同步技术,当多个进程在无同步下对文件进行I/O操作时,可能会导致竞争的出现文件锁的使用步骤通常如下给文件加锁执行文件I/O解锁文件使得其他进程能够给文件加锁stdio缓冲与加锁在使用文件锁时需要注意stdio缓冲区的问题在给文件加锁之前,缓冲区中可能包含我们不希望拥有的值,当在释放锁之后,缓冲区中内容的也可能会被无意写入文件,对此有以下几种办法使用read(),write())系统调用替代stdio()函数对文件加锁后,释放前都立即刷新s

2021-11-29 16:33:43 506 1

原创 tlpi: System V 消息队列

Syetem V消息队列System V消息队列的一些基本特征通过消息队列进行的通信是面向消息的,即读者接收到有写者写入的整条消息,读取消息的一部分或者一次读取多条消息的操作都是做不到的每条消息包含有一个用整数表示的类型,可以根据顺序读取消息,也可以根据消息的类型读取消息1.创建/打开一个消息队列msgget()用于创建一个新消息队列或者用于获取一个已有的消息队列#include<sys/types.h>#include<sys/msg.h>int msgget(

2021-11-28 16:19:15 140

原创 tlpi: 虚拟内存操作

虚拟内存操作1.改变内存保护mprotect()调用修改起始地址为addr,长度为length字节的虚拟内存地址中分页的保护#include<sys/mman.h>int mprotect(void *addr, size_t lenght, int prot); //成功:返回 0 失败:返回-1参数解释:addraddr必须为分页大小的整数倍length会被舍入到系统分页大小的下一个整数倍prot指定了新内存区域上的保护,可以有以下取值,

2021-11-28 11:21:32 236

原创 tlpi:内存映射(mmap, mumap,msync,mremap,remap_file_pages)

内存映射1.简介mmap()系统调用在调用进程的虚拟地址空间中创建一个新内存映射,映射的类型分为两种文件映射文件映射将一个文件的一部分直接映射到进程的虚拟地址空间中,映射之后,就可以通过进程的虚拟地址访问文件内容匿名映射匿名映射没有对应的文件,这种映射的分页会被初始化为0映射之间的共享,根据进程之间映射内容的变更是否可见,可以将映射分为私有的和共享的私有映射(MAP_PRIVATE)在映射内容上发生的变更对其他进程不可见,如果是文件映射,那么不会修改底层文件内容。内核采用了

2021-11-27 14:07:50 626

原创 tlpi: System V共享内存

System V共享内存1.概念共享内存允许多个进程之间共享物理内存的同一块区域,这块区域通常被称为共享内存段使用该共享内存段需要将该共享内存段附加到进程的虚拟地址空间中,该共享内存段会成为进程用户空间内存段的一部分,内核并不参与,与管道和消息队列需要将数据送入内核内存相比,共享内存的速度是所有IPC对象中最快的2.创建或打开一个共享内存段shmget()创建一个共享内存段或获取一个已有段的标识符,新创建的段中的内容会被置为0#include<sys/types.h>#

2021-11-26 20:48:13 126

原创 tlpi: POSIX信号量

POSIX信号量POSIX信号量总体上来说与System V相似,都是一个不小于0的整数SUSv3规定了两种类型的POSIX信号量命名信号量该信号量拥有一个名字,可以使用相同的名字来调用sem_open(),这样不同进程之间就能访问同一个信号量未命名信号量该信号量没有名字,它位于内存中一个预先商定的位置中,它可以在进程和线程之间共享当在进程之间共享时,信号量必须位于一个共享内存中当在线程中共享时,信号量必须位于线程可共享的区域,即堆或者全局变量中区别这两种信号量的最大区别在于

2021-11-24 21:06:24 193

原创 tlpi: POSIX消息队列(mq_open, mq_send, mq_receive, mq_close, mq_unlink)

POSIX消息队列消息队列是Linux IPC很常见的一种通信方式,它允许进程以消息的形式交换数据,下面将介绍POSIX消息队列POSIX消息队列的特征引用计数仅当所有当前使用队列的进程都关闭了队列之后才会对队列进行标记然后删除优先级队列中的消息是严格按照顺序排队的notify特性对消息队列由空变为非空时,POSIX消息队列允许队列向监听它的进程发送一条通知(notification)异步当一个进程向消息队列写入消息之前,并不需要某个进程在该队列上等待消息的到达读取也是

2021-11-23 15:58:14 2038

原创 tlpi:管道与FIFO

管道管道是UNIX系统上最古老的IPC方法,它最主要的功能就是使得一个命令的输出能过作为另一个命令的输入图例使用管道连接ls与wcls | wc 该过程实质上ls将其标准输出(stdout)绑定到了管道的写入端,wc将其标准输入(stdin)绑定到了管道的读取端管道的基本特征一个管道是一个字节流管道就是一个字节流,其传递的数据是顺序的,无法使用lseek()来随机的访问管道数据数据的读取当试图从一个空的管道中读取数据时将会被阻塞,直到有一个字节被写入管道如果管道的写

2021-11-22 17:17:27 311

原创 tlpi: 共享库高级特性

共享库高级特性动态加载库延迟加载通常情况下,当一个可执行文件开始执行后,动态链接器会加载程序的动态链接列表中的所有共享对象gcc -o prog prog.c libdemo1.so.1 libdemo2.so.1 libdemo3.so.1 LD_LIBRARY_PATH=. ./prog //此时三个共享库会全部被加载到程序中,不管他们当中的函数/变量有没有被使用这样势必会造成启动上速度的降低,使用dlopen API能够使得程序仅在使用到库中的函数时才将其加载

2021-11-21 20:05:03 570

原创 tlpi:共享库基础

共享库基础目标库构建程序得到一种简单方式是间每一个源文件编译成目标文件,然后将这些目标文件链接在一起形成可执行文件使用gcc的 -c选项即可将.c文件编译成.o文件链接的实际过程实际上是由一个单独的链接器ld来完成的,不过在Linux中应该总是使用gcc来间接地调用ld,因为gcc能够确保以正确的顺序来调用ld对象库在很多情况下,源代码会被多个程序共享,此时可以将他们编译一次,然后在需要的时候将他们链接进入不同的可执行文件中,一个.c文件就会生成一个.o目标文件,大量的目标文件势必会造成组织

2021-11-20 20:12:26 875

原创 位置无关代码

对于一个包含共享对象和可执行目标文件的模块来说,共享对象在装载前往往不能确定自己在进程虚拟空间的位置,具体原因有以下两点地址冲突问题由于共享对象会被很多其他模块共同使用,如果共享对象使用一个固定的装载地址,那么这个地址就不能被其他进程所使用,会造成空间的浪费共享库的更新问题共享库如果使用规固定地址,那么对共享库升级后共享库中的全局函数和变量地址就不能够改变,否则如果有应用程序在链接时就已经绑定到了这些地址,那么升级后他们必须重新进行链接因此,共享对象的装载时地址往往会在装载前一刻由操作

2021-11-20 17:47:39 1064

原创 tlpi:DAEMON

DAEMON(守护进程)1.特征DAEMON是一种具备以下特征的进程它的生命周期很长,通常,一个DAEMON会在系统启动时被创建,运行至系统终止它在后台运行并且不具有控制终端,这确保了内核不会为其生成任何的作业控制信号(SIGTTIN、SIGTOUT等)以及终端相关信号(SIGINT, SIGSTOP等)一些常见的daemon:cron:一个在规定时间执行命令的daemonsshd:安全shell daemon,允许在远程主机上使用一个安全的通信协议来登录系统httpd:HTTP服务器

2021-11-20 14:27:38 820

原创 tlpi:进程优先级和调度(getpriority...)

进程优先级和调度进程优先级(nice值)进程优先级nice值会影响CPU的调度策略,每个进程都拥有一个nice值,其取值范围为-20~-19,默认值为0在传统UNIX实现中,只有特权进程才能够赋给自己一个负的优先级,非特权级进程只能够降低自己的优先级,即赋予一个正值这样做的话他们对于其他进程来说就很"nice"了通过fork()会继承nice的值,并且该值会在exec()中得以保存获取和修改nice值#include<sys/resourece.h>int getpriori

2021-11-19 14:47:38 479

原创 tlpi:进程组,会话,孤儿进程组

进程组概念进程组的组成进程组由一个或者多个**共享同一进程组标识符(PGID)**的进程组成进程组首进程一个进程组拥有一个进程组首进程,该进程是创建该组的进程,它的PID与进程组的ID(PGID)相同进程组的继承新的进程会继承它的父进程所属于的进程组ID,即使用fork()创建一个子进程时,这个进程会与它的父进程属于同一个进程组进程组的生命周期进程组的生命周期开始于首进程创建组的时刻,结束于最后一个成员退出组的时刻一个进程可以因为终止而退出进程组,也可能因为加入了另一

2021-11-18 15:56:40 190

原创 tlpi:更多细节(pthread_sigmask, pthread_kill, pthread_sigqueue, sigwait,

更多细节线程栈创建线程时,每个线程都有一个属于自己的栈,且大小固定,在Linux/x86-32架构下,除了主线程之外,所有的栈的缺省大小为2MB可以通过pthread_attr_setstacksize(),pthread_attr_setstack()等系统调用控制线程栈的大小可以采用调用sysconf(_SC_THREAD_STACK_MIN)来确定可采用的线程栈的最小值线程与信号信号模型先于线程模型出现,因此将两者结合使用会产生很多棘手情况UNIX的信号模型映射到线程中关于信号有很多方

2021-11-17 21:49:00 404

原创 tlpi:线程取消(pthread_cancel...)

线程取消pthread_cancel#include<pthread.h>int pthread_cancel(pthread_t thread); //成功:返回0 失败:返回正数函数pthread_cancel()可以向由thread指定的线程发送一个取消请求发送取消请求后,函数pthread_cancel()当立即返回,不会等待目标线程的退出取消的状态和类型当执行取消操作,即pthread_cancel时,取消的结果取决于取消的状态和类型,可以通过

2021-11-16 18:25:00 2068 1

原创 tlpi:线程安全和每线程存储(pthread_create...)

线程安全与每数据存储1.线程安全若函数可以同时供多个线程同时安全调用,暗恶魔称之为线程安全函数,如果函数不是线程安全,则不能够并发调用实现线程安全的方式将函数与互斥量关联使用,在调用函数时将其锁定,在函数返回时解锁该方法的优点在于简单,但是这也就意味着同时只能有一个线程执行该函数,如果各线程在执行此函数时耗费了相当多的时间,那么该执行方式就相当于串行了,导致并发能力的丧失将共享变量与互斥量关联起来即在函数即将进入临界区时去获得和释放互斥量,这允许多个线程去并发执行一个函数

2021-11-16 14:40:42 564

原创 tlpi:线程的同步

互斥量一些具体API可以看这篇博文[互斥锁]互斥量的死锁有时,一个线程需要同时访问两个或更多不同的共享资源,而每个资源有都有不同的互斥量管理,当超过一个线程加锁同一组互斥量时,就有可能发生死锁例:线程A先执行步骤1,线程2再执行步骤1,紧接着线程A执行步骤2,此时因为mutex2被线程B所占有,所以A将进入阻塞状态,线程B继续执行步骤2,此时因为mutex1被线程A所占据,所以B也将陷入阻塞状态,一个经典的死锁就出现了解决方案定义互斥量之间的层级关系当多个线程对一

2021-11-16 09:35:15 185

原创 tlpi:线程基础(pthread_create(), pthread_join()...)

线程介绍概念一个进程可以包含多个线程,统一程序中的所有数据均会独立地执行相同的程序,并且共享一份全局内存区域,其中包括初始化数据段,未初始化数据段,以及堆内存段每个线程都具有各自的私有栈空间,不过当然是在进程的地址空间内部布局分布如下图同一个进程中的多个线程可以并发执行,在多处理器环境下,多个线程可以同时并行线程组id在所有的线程组中,所有的线程共享同一个进程ID,同一个进程组ID,并且这两个值永远相同一个线程组中的所有线程都拥有一个唯一的线程标识符(tid),线程id不仅在线程组中唯

2021-11-16 09:29:38 621

原创 tlpi:进程的执行(exec()...)

进程的执行(exec)execveececve系统调用可以将新程序加载到调用进程的内存空间,在这一过程中,将丢弃现有的进程的文本段,同时,进程的堆栈段,数据都会被新进程的相应部件所替换在执行完各种初始化代码之后(比如C++的构造函数),新的程序会从main处开始执行通常的使用方法是使用fork创建子进程,然后使用execve()执行新进程#include<unistd.h>int execve(const char*pathname, char *const argv[], ch

2021-11-16 09:26:07 161

原创 tlpi:进程的监控(wait(),waitpid)

wait系统调用wait等来调用进程的任何一个子进程终止,同时将该子进程的信息存储在status中#include<sys/wait.h>pid_t wait(int *status) //成功:返回终止的子进程ID 失败:返回-1如果调用之前并没有子进程终止,那么调用将一直阻塞,直到某一个子进程终止如果调用进程的所有子进程都已经终止了,那么wait将返回-1,并且将errno置为ECHILD通常使用如下代码来等待所有子进程退出while((childP..

2021-11-16 09:23:34 439

原创 tlpi:进程的退出(exit(),_exit(),atexit(),on_eixt())

_exit()通常进程有两种终止方式,一种是异常终止,当进程接受到某一个信号,而该信号的默认动作又是终止当前进程(term | core)时,进程就会被异常终止此外,进程可以使用_exit()系统调用来正常终止#include<unistd.h>void _exit(int status); //return 0 表示正常退出,非0表示异常退出参数status定义了进程的终止状态,父进程可以使用wait来获取该状态status虽然为int类型,但是只有低8位..

2021-11-16 09:22:01 91

原创 tlpi:创建新进程(fork())

fork:创建一个新进程(child),几近于对调用进程(parent)的翻版#include<unistd.h>pid_t fork(void)当完成对fork的调用之后,将会存在两个进程,即一个子进程一个父进程,每个进程都会从fork()的返回处继续执行进程间地址空间的关系父进程与子进程将执行相同的程序文本段,但却拥有不同的栈段,数据段,以及堆段拷贝 (采用写时复制技术时另说)子进程的栈、数据以及栈段开始时是对父进程内存相应各部分的完全复制执行fork时,每个进程均可

2021-11-16 09:13:31 79

空空如也

空空如也

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

TA关注的人

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