02 2023 档案

摘要:原因: 如有两个线程,两把互斥锁,线程1先对互斥锁A上锁,延时,然后在对互斥锁B上锁;二线程2先对互斥锁B上锁,延时,再对互斥锁A上锁,这样就会死锁,因为两线程以不同顺序拿到了对方的锁,并且不能解锁; 解决方式: 1. 以相同的顺序加锁 2. 使用pthread_mutex_trylock()函数 阅读全文
posted @ 2023-02-26 23:02 踏浪而来的人 阅读(22) 评论(0) 推荐(0)
摘要:线程信号量可以实现线程的互斥和线程的同步。 信号量的数据类型:sem_t 信号量本质上是一个非负整数计数器,是共享资源的数目(即共享资源还剩下几个,信号量的值大于或等于0时,线程才不阻塞) 信号量的创建和销毁: 参数: sem:信号量指针 pshared:是否在进程之间共享;0为不共享,1为共享 v 阅读全文
posted @ 2023-02-26 22:50 踏浪而来的人 阅读(124) 评论(0) 推荐(0)
摘要:1. 条件变量(通互斥锁一起使用,互斥锁用来保护等待队列的) 2. 线程信号量 条件变量: 条件变量的内部是一个等待队列,这个队列中放置阻塞的线程,线程在这个队列中等待通知。 因为这个等待队列也时一个共享资源,所以也要用一把互斥锁来保护,即对等待队列上锁。 队列中的线程等特定的条件发生,当条件不满足 阅读全文
posted @ 2023-02-26 21:10 踏浪而来的人 阅读(27) 评论(0) 推荐(0)
摘要:1. 互斥锁 2. 读写硕 3. 线程信号量 互斥锁: 互斥锁的数据类型:pthread_mutex_t 互斥锁是一种加锁的方法来控制对共享资源的访问。同一时刻只能由一个线程掌握某个互斥锁(就是有一把互斥锁),一个线程对共享资源上锁了,其他线程希望上锁一个已经上了互 斥锁的共享资源,那么这些线程将会 阅读全文
posted @ 2023-02-26 10:33 踏浪而来的人 阅读(161) 评论(0) 推荐(0)
摘要:互斥: 相互排斥,表示线程对共享资源的访问时相互排斥的,即不能同时操作(一个线程对共享资源写时,另外一个线程不能再对这个共享资源进行读写),保证线程的安全,互斥不能保证 线程执行的先后顺序 实现互斥的方式: 互斥锁 读写锁 线程信号量 同步: 包含了互斥,即既保证了线程的安全,又能保证线程执行的先后 阅读全文
posted @ 2023-02-26 09:25 踏浪而来的人 阅读(41) 评论(0) 推荐(0)
摘要:static static有两种使用场景: 1. 修饰变量 修饰局部变量(称为静态局部变量):出了这个变量的作用域后,该变量不会被销毁。该变量存储在静态存储区 修饰全局变量(称为静态全局变量):和普通全局变量的区别在于这个被static修饰的全局变量不能在其他源文件中使用,(即不能在其他源文件中用e 阅读全文
posted @ 2023-02-23 16:55 踏浪而来的人 阅读(106) 评论(0) 推荐(0)
摘要:线程的属性实现线程创建的时候(pthread_create)指定 线程属性的初始化和销毁 线程属性的结构: 如果线程设置了分离状态这个属性,那么可以在线程结束时,主线程不用调用pthreat_join函数来回收这个线程的资源,他会自动回收 获得和设置分离属性: 阅读全文
posted @ 2023-02-22 23:13 踏浪而来的人 阅读(26) 评论(0) 推荐(0)
摘要:状态转换: 阅读全文
posted @ 2023-02-22 22:33 踏浪而来的人 阅读(20) 评论(0) 推荐(0)
摘要:当线程调用pthread_exit函数时,如果execute为非0,将执行线程push的清理函数 注意: push和pop函数是成对存在的,先push的清理函数后调用 阅读全文
posted @ 2023-02-22 22:30 踏浪而来的人 阅读(21) 评论(0) 推荐(0)
摘要:线程终止的方式: 1. 主动终止 a. 线程运行函数中调用return b. 线程中调用pthread_exit函数 2. 被动终止 线程可以被同一进程的其他线程取消,其他线程调用pthread_cancel函数 不管在哪个线程中调用exit()、_exit、_Exit函数,进程都会终止 阅读全文
posted @ 2023-02-22 22:16 踏浪而来的人 阅读(28) 评论(0) 推荐(0)
摘要:pthread_creat函数 头文件: #include <pthread.h> 函数原型: int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), voi 阅读全文
posted @ 2023-02-22 21:17 踏浪而来的人 阅读(22) 评论(0) 推荐(0)
摘要:在一个c程序中,将内存分为: 代码区: 常量区:存放的一些常量 静态存储区:存放全局和静态变量 堆: 栈: int a = 0; //全局初始化区 char *p1; //全局未初始化区 main() { int b;// 栈 char s[] = "abc"; //就在栈上 char *p2; / 阅读全文
posted @ 2023-02-22 15:20 踏浪而来的人 阅读(36) 评论(0) 推荐(0)
摘要:所有进程共享3~4G的内核空间,所以基于内核之间的通信能够实现(为了保证安全,每个进程的用户地址空间都是独立的,一般而言一个进程不能直接访问另一个进程的地址空间,不过内核空间是每个进程都共享的,所以进程之间想要进行信息交换就必须通过内核)。 线程之间的通信: 1. 不同进程的线程之间要进行通信,那就 阅读全文
posted @ 2023-02-21 16:24 踏浪而来的人 阅读(25) 评论(0) 推荐(0)
摘要:一个程序中数据的计算是通过CPU。那么CPU中的数据来自哪里呢? 1. 内存(物理内存):所以一个进程的虚拟内存操作后会通过MMU将虚拟内存中的数据映射到物理内存 2. 寄存器(cpu的寄存器):当一个变量的优化级别较高时,会将变量存到cpu的寄存器中 用信号理解volatile 代码说明: #in 阅读全文
posted @ 2023-02-21 10:22 踏浪而来的人 阅读(108) 评论(0) 推荐(0)
摘要:信号无优先级。 信号是异步事件; 异步事件:a进程向b进程发送了一个信号,进程a不用等到进程b响应才往下执行 同步事件:a进程向b进程发送了一个信号,进程a要阻塞到进程b响应才往下执行 1~31的信号:非实时信号,发送的信号可能丢失,不支持信号排队 32~61的信号:实时信号,支持信号排队,发送的多 阅读全文
posted @ 2023-02-20 22:20 踏浪而来的人 阅读(179) 评论(0) 推荐(0)
摘要:当创建一个子进程后,该进程会进入就绪状态,再根据系统的调度,获得时间片,就进入运行状态,在运行状态的进程调用return等进程就结束了;如果在运行状态的进程调用read、write等带阻塞的函数,进程就会进入挂起状态。 阅读全文
posted @ 2023-02-19 22:13 踏浪而来的人 阅读(30) 评论(0) 推荐(0)
摘要:exec函数是为了在子进程中执行其他的可执行程序(代码替换) 子进程调用exec函数并不创建新的进程,所以前后进程的ID不会改变,exec函数只是用另一个新程序代替当前进程的正文、数据、堆、栈,exec函数结束后(成功就不返回了,失败会返回-1),exec函数后的代码不会执行 l(list):参数列 阅读全文
posted @ 2023-02-19 22:06 踏浪而来的人 阅读(42) 评论(0) 推荐(0)
摘要:wait()函数:以阻塞的方式等待子进程退出,防止僵尸进程的产生 头文件: #include <sys/types.h> #include <sys/wait.h> pid_t waitpid(pid_t pid, int *wstatus, int options); 原型: pid_t wait 阅读全文
posted @ 2023-02-19 18:01 踏浪而来的人 阅读(97) 评论(0) 推荐(0)
摘要:守护进程: 孤儿进程: 僵尸进程: 阅读全文
posted @ 2023-02-19 17:16 踏浪而来的人 阅读(18) 评论(0) 推荐(0)
摘要:进程链#include <stdio.h> #include <sys/types.h> #include <unistd.h> int main(void) { pid_t pid; int i; //printf("pid = %d\n",getpid()); for(i = 0; i< 5;i 阅读全文
posted @ 2023-02-19 16:49 踏浪而来的人 阅读(24) 评论(0) 推荐(0)
摘要:操作文件内核中的结构变化: 在创建一个子进程时,子进程也会有一个进程表项,子进程进程表项中的文件描述符表是复制的父进程的。 阅读全文
posted @ 2023-02-19 16:02 踏浪而来的人 阅读(14) 评论(0) 推荐(0)
摘要:在fork之前的printf和write函数只会父进程调用一次,子进程不会调用,因为那时子进程还没有创建出来。当fork时,子进程被创建,程序只会往下顺序执行,但是前面父进程分配的数据段、堆、栈(如红框)会被复制一份到子进程 输出如下: 阅读全文
posted @ 2023-02-19 15:39 踏浪而来的人 阅读(21) 评论(0) 推荐(0)
摘要:1. 主进程在fork出一个子进程后,会将自己4G的空间复制一份给子进程(包括代码段、数据段、堆、栈),代码段共享同一物理内存,因为子进程中的代码和父进程中的代码是一样的,只是对pid有一个判断,才会走不同的分支; 输出: 红框中的代码在父进程和子进程都有一份,他们是一样的,只是他们通过判断是父进程 阅读全文
posted @ 2023-02-19 10:51 踏浪而来的人 阅读(292) 评论(0) 推荐(0)
摘要:ps -aux输出的进程信息: 进程的状态: 进程状态的变化关系: 阅读全文
posted @ 2023-02-16 22:25 踏浪而来的人 阅读(25) 评论(0) 推荐(0)
摘要:区别: 全缓存刷新io缓存的条件: 1. 文件写满; 2. 关闭文件; 3. 进程以return、exit终止 阅读全文
posted @ 2023-02-16 22:04 踏浪而来的人 阅读(17) 评论(0) 推荐(0)
摘要:c程序的启动过程(进程的启动过程): 首先,每个c程序都是从主函数开始,但是在主函数调用之前内核会启动一个特殊的例程,叫启动例程,然后这个启动例程会调用main函数 每个进程在终止前都会调用一个终止函数,终止函数的默认动作就是清缓存、释放资源等,当然也可以自己定义终止函数,然后再向内核注册,让进程终 阅读全文
posted @ 2023-02-16 21:45 踏浪而来的人 阅读(115) 评论(0) 推荐(0)
摘要:内核中每个启动的进程都是对task_struct结构体(进程表项、进程控制块pcb process control block)的抽象 内核中进程的结构: 内核中为每个进程维护了一个task_struct的结构体,该结构体就是对进程的抽象,进程的所有状态、信息、策略等都用这个结构体表示。 进程可以操 阅读全文
posted @ 2023-02-16 21:17 踏浪而来的人 阅读(29) 评论(0) 推荐(0)
摘要:硬盘上的文件系统包括:目录项、i节点、数据块 当在磁盘上有个文件(iotek.txt)时,在磁盘上的会保存它的目录项,目录项中有i节点标号,通过编号可以找到i节点;然后在i节点中也保存着数据块的编号和硬链接数(1),数据块中就存放着文件内容。 当创建一个硬链接(h_iotek)时, 会在磁盘上创建一 阅读全文
posted @ 2023-02-15 22:56 踏浪而来的人 阅读(55) 评论(0) 推荐(0)
摘要:文件的属性是用一个结构体来封装的: 文件属性的操作函数: 文件的类型: 函数操作: 文件权限: access函数(检查指定文件是否具有某种操作) 头文件: #include <unistd.h> 原型: int access(const char *pathname,int mode) 参数: pa 阅读全文
posted @ 2023-02-15 21:56 踏浪而来的人 阅读(19) 评论(0) 推荐(0)
摘要:IO处理的五种模型 进程间的信号 linux根目录结构和linux内核目录结构的区别 文件系统 架构是什么 阅读全文
posted @ 2023-02-15 20:55 踏浪而来的人 阅读(37) 评论(0) 推荐(0)
摘要:1. dup2(实现输入/输出重定向) 头文件: #include <unistd.h> 原型: int dup2(int oldfd, int newfd); 参数: oldfd:被复制的文件描述符 newfd:新的文件描述符,将oldfd的文件表项指针复制给newfd的文件表项指针,即newfd 阅读全文
posted @ 2023-02-15 15:34 踏浪而来的人 阅读(18) 评论(0) 推荐(0)
摘要:1. 环境变量 linux系统中,环境变量分为系统级和用户级: 系统级: 在/etc/environment配置文件中的环境变量对所有进程有效 在/etc/profile配置文件中的环境变量对所有用户有效 用户级:在~/.profile配置文件中的环境变量对当前用户有效 在~/.bashrc配置文件 阅读全文
posted @ 2023-02-15 11:15 踏浪而来的人 阅读(34) 评论(0) 推荐(0)
摘要:在用户空间操作文件:就是通过些文件描述符来对文件进行读写操作 在内核空间对文件的操作呢? 在内核中用三种数据结构(都是些结构体)来表示一个打开的文件(即将这三种数据结构来组织成一个文件): 在用户空间调用open、read、write等会在内核中产生这三种数据结构(结构体)来保存文件的状态信息 阅读全文
posted @ 2023-02-15 10:44 踏浪而来的人 阅读(23) 评论(0) 推荐(0)
摘要:1. open 头文件: #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> 原型: int open(const char* pathname, int flags);//这种原型是打开一个已经存在的文件 int open 阅读全文
posted @ 2023-02-15 10:23 踏浪而来的人 阅读(56) 评论(0) 推荐(0)
摘要:文件io(系统调用):不带缓存且都由内核提供的系统调用。有open()、close()、read()、write() open()函数要用到的头文件: #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> 标准头文件所在的系统 阅读全文
posted @ 2023-02-13 22:43 踏浪而来的人 阅读(47) 评论(0) 推荐(0)
摘要:一个进程中默认打开了STDIN(标准输入)、STDOUT(标准输入)、STDERR(标准错误) 标准io:标准io库(stdio)提供的带缓存的io,可提高效率(减少系统点用),也会有系统调用,只是在缓存达到某种条件是,才会执行系统点用 带缓存的实质:是将要输入或者输出的数据,先放到缓存中,然后在适 阅读全文
posted @ 2023-02-13 20:45 踏浪而来的人 阅读(116) 评论(0) 推荐(0)
摘要:c程序的内存分配: 执行程序会将程序加载到内存,内存大体上被分为三个区:栈段、堆段、数据段(全局变量和static变量) 栈:局部变量和形式参数会保存在栈区,函数调用完之后,释放栈帧和函数中的局部变量。 堆:堆区空间远大于栈区空间,可自行分配,并在使用完后手动释放内存空间。 数据段:存放全局变量和s 阅读全文
posted @ 2023-02-10 15:46 踏浪而来的人 阅读(23) 评论(0) 推荐(0)
摘要:Transort层的作用: 区分host和controler之间的hci数据是commond、event、acl、sco。比如说H4这种transport,它在hci数据前加一字节的type,来区分这四种不同的数据。 type: 0x01(commond):当controler识别到type为0x0 阅读全文
posted @ 2023-02-09 23:37 踏浪而来的人 阅读(143) 评论(0) 推荐(0)
摘要:每个进程启动时操作系统都会给其分配4G的虚拟内存 这4个G是操作系统看到的内存布局,但是其会映射到物理内存,实际的物理内存是如下图: 所有的程序都是由指令构成的,如加减乘除、条件判断等最终都是编译成一些指令 数据段: 代码段: 这里保存的就是我们写的代码,更准确的是编译后的可执行机器指令 怎么从虚拟 阅读全文
posted @ 2023-02-09 23:23 踏浪而来的人 阅读(72) 评论(0) 推荐(0)