- 博客(43)
- 收藏
- 关注

原创 Linux下使用socket的API编程实现服务端和客户端进行通信
Socket(套接字),在Linux环境下,用于表示进程间网络通信的特殊文件类型。本质为内核借助缓冲区形成的伪文件。本质是文件,那么理所当然的,我们可以使用文件描述符引用套接字。与管道类似的,Linux系统将其封装成文件的目的是为了统一接口,使得读写套接字和读写文件的操作一致。区别是管道主要应用于本地进程间通信,而套接字多应用于网络进程间数据的传递。在TCP/IP协议中,“IP地址+TCP或UDP端口号”唯一标识网络通讯中的一个进程。“IP地址+端口号...
2021-12-14 20:00:33
3861
原创 进程和线程的区别
而线程是进程的一部分,共享进程的资源,切换开销小,通信和同步相对方便。子进程执行的代码和父进程执行的代码是相同的,但是它们的进程ID不同。线程:线程是进程的一部分,线程间的切换开销较小,因为它们共享了进程的地址空间和资源,只需要切换线程的执行上下文即可,开销相对较小。进程:由于进程拥有独立的地址空间,进程间的切换开销较大,涉及到页表的切换和资源的切换,因此进程间的上下文切换开销较大。线程:线程是进程的一部分,线程之间可以直接共享进程的地址空间和全局变量,因此线程之间的通信和同步相对容易。
2023-07-28 14:50:11
1353
原创 深入理解C++中的拷贝构造函数与移动语义
当类中包含指针或资源时,应该显式定义自己的拷贝构造函数,以执行深拷贝操作。深拷贝确保在新对象中创建一个完全独立的数据副本,避免资源共享和悬空指针问题。
2023-07-27 09:33:14
588
原创 C++:stat函数
函数原型:int stat(const char *pathname, struct stat *statbuf)函数作用:用于获取文件状态信息使用函数需要包含头文件: #include #include #include stat函数在 statbuf 指向的缓冲区中返回有关文件的信息。返回值:成功返回0;失败返回-1
2022-09-16 10:41:02
6632
原创 C++:多态的实现
多态:按字面的意思就是多种形态。当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态。C++ 多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。
2022-09-13 16:13:12
446
原创 C++中类静态方法与实例方法的区别
静态方法在编译的时候就已经加载了并分配了内存,而实例方法只有在对象创建之后才会为实例方法分配内存。因此调用静态方法速度快,但是会占用内存。静态方法只能访问静态成员,不能访问实例成员;而实例方法可以访问静态成员和实例成员。静态方法归整个类所有,因此调用它不需要实例化,可以直接调用(实例方法必须先进行实例化。...
2022-08-11 17:44:02
639
原创 多线程实现客户端与服务端通信(初级版本)
使用多线程, 让主线程接受新连接, 让子线程处理与客户端通信; 使用多线程要将线程设置为分离属性, 让线程在退出之后自己回收资源.服务端代码:server.c编译之后启动服务端,使用nc命令nc:可以作为client发起TCP或UDP连接 。同时开启多个终端(模拟客户端)来测试。测试结果如下,多个客户端向服务器发出请求,并得到回应,实现了多线程通信。......
2022-06-19 14:30:56
613
原创 算法题:完全二叉树的权值
问题描述:给定一棵包含 N 个节点的完全二叉树,树上每个节点都有一个权值,按从 上到下、从左到右的顺序依次是 A1, A2, ··· AN,如下图所示:现在要把相同深度的节点的权值加在一起,他想知道哪个深度的节点 权值之和最大?如果有多个深度的权值和同为最大,请你输出其中最小的深度。注:根的深度是 1。输入描述:第一行包含一个整数 N(1≤N≤100000)。第二行包含 N 个整数A1 ,A2 ,⋅⋅⋅AN(−100000 ≤Ai ≤100000 )。输出...
2022-02-21 13:22:45
873
原创 C++:sort函数
sort函数用于C++中,对给定区间所有元素进行排序,默认为升序,也可进行降序排序。sort函数进行排序的时间复杂度为n*log2n,比冒泡之类的排序算法效率要高。使用sort函数要包含头文件为#include<algorithm>的c++标准库。sort函数原型:sort(首元素地址(必填), 尾元素地址的下一个地址(必填), 比较函数(非必填));sort函数默认从小到大排序;如果想改变排序顺序,就是用第三个参数从大到小排序。...
2022-02-20 14:56:30
967
原创 算法题:数列求值
题目要求:给定数列 1, 1, 1, 3, 5, 9, 17,⋯,从第 4项开始,每项都是前 3项的和。求第 2019032420190324 项的最后 4位数字分析:这道题很容易就想到斐波那契数列,这正是它的变型。注意需要先取余,如果先将每项的结果求出来,最后再对其取余的话,求和的数据非常大会溢出。使用递归的话,耗费的的内存是比较大的。重点:每一步取余,和算出最终结果取余结果一致解法一:#include <iostream>using namespace st.
2022-02-18 21:53:56
546
原创 算法题:在 1 到 2019中,含有0,1,2,9所有这样的数的平方和是多少?
解题关键就是 istrue函数编写:如果一个属取余10后,符合余数0,1,2,9就是要找的数,如果不是就整除10,最终为0就不做任何操作退出循环。代码如下:#include <iostream>using namespace std;int istrue(int a) { int res = 0; while (a) { temp = a % 10; if (temp == 0 || temp == 1 || temp == 2 || temp =...
2022-02-18 20:22:33
351
原创 多进程实现客户端与服务端通信
在不使用多进程时(一个客户一个服务器)进行通信的例子不仅功能简单,而且简单到几乎没有什么错误处理,我们知道,系统调用不能保证每次都成功,必须进行出错处理,这样一方面可以保证程序逻辑正常,另一方面可以迅速得到故障信息。为使错误处理的代码不影响主程序的可读性,提高编程效率我们把与socket相关的一些系统函数加上错误处理代码包装成新的函数,做成一个模块wrap.c:#include <stdlib.h>#include <stdio.h>#i...
2021-12-16 15:09:56
1089
原创 网络基础(分层模型,网络协议)
在计算机网络当中有两类分层模型:OSI七层模型和TCP/IP四层模型;以下做简单的介绍OSI七层模型物理层:主要定义物理设备标准,如网线的接口类型、光纤的接口类型、各种传输介质的传输速率等。它的主要作用是传输比特流(就是由1、0转化为电流强弱来进行传输,到达目的地后再转化为1、0,也就是我们常说的数模转换与模数转换)。这一层的数据叫做比特。 数据链路层:定义了如何让格式化数据以帧为单位进行传输,以及如何让控制对物理介质的访问。这一层通常还提供错误检测和纠正,以确保数据的可靠...
2021-12-07 21:08:56
427
原创 利用信号量解决线程同步与互斥——以生产者消费者模型为例
线程同步和互斥的概念线程同步就是把同一进程环境下的一组并发线程,因直接制约而互相发送消息而进行互相合作、互相等待,使得各线程按一定的速度执行的过程。互斥是指不允许两个以上的共享该资源的并发线程同时进入临界区。其中直接制约是指同一进程环境下的一组并发线程,各自的执行结果互为对方的执行条件,从而限制各进程的执行速度的过程。由于共享某一共有资源而引起的在临界区内不允许并发线程交叉执行的现象,由共享共有资源而造成的对并发线程执行速度的间接制约简称为间接制约。受间接制约的类中各程序段在执行顺序上是...
2021-11-29 11:59:38
963
原创 使用条件变量实现生产者和消费者模型
生产者消费者模型,使用链表来实现,生产者依次创建链表节点,消费者访问链表中节点的数据域,然后删除(消费)。 创建两个线程来实现的过程中会产生一些问题,例如节点还未创建出来,消费者线程先得到CPU先执行,会出现错误等。 因此引入条件变量,等待生产者进程执行后,消费者进程在执行就不会发生错误了。条件变量条件本身不是锁!但它也可以造成线程阻塞。通常与互斥锁配合使用。给多线程提供一个会合的场所。使用互斥量保护共享数据; 使用条件变量可以使线程阻塞, ...
2021-11-28 20:50:32
477
原创 线程同步及互斥锁
线程同步的概念线程同步,指一个线程发出某一功能调用时,在没有得到结果之前,该调用不返回。同时其它线程为保证数据一致性,不能调用该功能。线程同步的例子创建两个线程,让两个线程共享一个全局变量int number, 然后让每个线程数5000次数,看最后打印出这个number值是多少?线程A代码片段:4.1 线程同步的概念线程同步,指一个线程发出某一功能调用时,在没有得到结果之前,该调用不返回。同时其它线程为保证数据一致性,不能调用该功能。4.2 线程同步的例子创建两个线程,让两个
2021-11-28 20:19:44
459
原创 pthread_detach函数
线程分离状态:指定该状态,线程主动与主控线程断开关系。使用pthread_exit或者线程自动结束后,其退出状态不由其他线程获取,而直接自己自动释放。网络、多线程服务器常用。进程若有该机制,将不会产生僵尸进程。僵尸进程的产生主要由于进程死后,大部分资源被释放,一点残留资源仍存于系统中,导致内核认为该进程仍存在。也可使用 pthread_create函数参2(线程属性)来设置线程分离。pthread_detach函数是在创建线程之后调用的。函数描述:...
2021-11-28 12:35:02
15154
原创 pthread_exit函数
在线程中禁止调用exit函数,否则会导致整个进程退出,取而代之的是调用pthread_exit函数,这个函数是使一个线程退出,如果主线程调用pthread_exit函数也不会使整个进程退出,不影响其他线程的执行。函数描述:将单个线程退出 函数原型:void pthread_exit(void *retval); 函数参数:retval表示线程退出状态,通常传NULL需要注意一点,pthread_exit或者return返回的指针所指向的内存单...
2021-11-24 23:00:30
7849
1
原创 pthread_create创建线程
什么是线程?轻量级的进程(LWP:light weight process),在Linux环境下线程的本质仍是进程。 进程:拥有独立的地址空间,拥有PCB,相当于独居。 线程:有PCB,但没有独立的地址空间,多个线程共享进程空间,相当于合租。线程是系统调度进程执行的最小单位。实际上,无论是创建进程的fork,还是创建线程的pthread_create,底层实现都是调用同一个内核函数 clone。如果复制对方的地址空间,那么就产出一个“进程”; 如果共享对方...
2021-11-23 19:33:38
2758
原创 守护进程~
什么是守护进程Daemon(精灵)进程,是Linux中的后台服务进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。一般采用以d结尾的名字,如vsftpdLinux后台的一些系统服务进程,没有控制终端,不能直接和用户交互。不受用户登录、注销的影响,一直在运行着,他们都是守护进程。如:ftp服务器;nfs服务器等。守护进程的特点Linux后台服务进程 独立于控制终端 周期性的执行某种任务 不受用户登陆和注销的影响 一般采用以d结...
2021-11-23 16:25:39
518
原创 SIGCHLD信号
产生SIGCHLD信号的条件子进程结束的时候 子进程收到SIGSTOP信号 当子进程停止时,收到SIGCONT信号SIGCHLD信号的作用子进程退出后,内核会给它的父进程发送SIGCHLD信号,父进程收到这个信号后可以对子进程进行回收。使用SIGCHLD信号完成对子进程的回收可以避免父进程阻塞等待而不能执行其他操作,只有当父进程收到SIGCHLD信号之后才去调用信号捕捉函数完成对子进程的回收,未收到SIGCHLD信号之前可以处理其他操作。...
2021-11-22 11:22:27
1034
原创 信号集(未决信号集,阻塞信号集)
未决信号集和阻塞信号集的关系阻塞信号集是当前进程要阻塞的信号的集合,未决信号集是当前进程中还处于未决状态的信号的集合,这两个集合存储在内核的PCB中。下面以SIGINT为例说明信号未决信号集和阻塞信号集的关系: 当进程收到一个SIGINT信号(信号编号为2),首先这个信号会保存在未决信号集合中,此时对应的2号编号的这个位置上置为1,表示处于未决状态;在这个信号需要被处理之前首先要在阻塞信号集中的编号为2的位置上去检查该值是否为1: ...
2021-11-21 22:51:19
2733
原创 setitimer函数
函数原型:int setitimer(int which, const struct itimerval *new_value,struct itimerval *old_value);函数功能:设置定时器(闹钟),可代替alarm函数,精度微秒us,可以实现周期定时。函数返回值:成功:0; 失败:-1,设置errno值函数的参数解释:1. which:指定定时方式 自然定时:ITIMER_REAL ...
2021-11-18 21:50:23
1066
原创 信号相关知识
信号的概念信号是信息的载体,Linux/UNIX 环境下,古老、经典的通信方式, 现下依然是主要的通信手段。信号的特点简单 不能携带大量信息 满足某个特点条件才会产生信号的机制进程A给进程B发送信号,进程B收到信号之前执行自己的代码,收到信号后,不管执行到程序的什么位置,都要暂停运行,去处理信号,处理完毕后再继续执行。与硬件中断类似——异步模式。但信号是软件层面上实现的中断,早期常被称为“软中断”。每个进程收到的所有信号,都是由内核负责发送的。...
2021-11-16 22:45:13
95
原创 用mmap函数建立存储映射区进行进程间通信
内存映射区简介存储映射I/O (Memory-mapped I/O) 使一个磁盘文件与存储空间中的一个缓冲区相映射。从缓冲区中取数据,就相当于读文件中的相应字节;将数据写入缓冲区,则会将数据写入文件。这样,就可在不使用read和write函数的情况下,使用地址(指针)完成I/O操作。使用存储映射这种方法,首先应通知内核,将一个指定文件映射到存储区域中。这个映射工作可以通过mmap函数来实现。mmap函数函数作用:建...
2021-11-15 22:40:40
405
原创 如何设置管道为非阻塞
LINUX中,管道的读写两端是阻塞的,例如读端会一直阻塞直到写端写入内容,才会立即返回。其实也可以将管道中的读或写端设置为非阻塞状态。 如果要设置读端或者写端为非阻塞,参考以下三个步骤: int flags = fcntl(fd[0], F_GETFL, 0); flag |= O_NONBLOCK; fcntl(fd[0], F_SETFL, flags); 以读端设置为非阻塞为例:写端没有关闭,管道中没有数据可读...
2021-11-15 21:38:53
2663
3
原创 使用管道完成父子进程间通信
什么是进程间通信Linux环境下,进程地址空间相互独立,每个进程各自有不同的用户地址空间。任何一个进程的全局变量在另一个进程中都看不到,所以进程和进程之间不能相互访问,要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信(IPC,InterProcess Communication)。什么是管道管道是一种最基本的IPC机制,也称匿名管道,应用于有血缘关系的进程之...
2021-11-13 20:16:41
5480
原创 僵尸进程~
1. 僵尸进程(1)僵尸进程概述什么是僵尸进程?在Linux系统中,任何一个子进程在调用exit()函数结束运行后,内核会释放该进程的所有资源,包括占用的内存和打开的文件等。同时,也会留下一个叫做僵尸进程(Zombie)的数据结构,Zombie中存储了该进程的进程号、退出码、退出状态、使用的CPU时间等信息。即僵尸进程是早已死亡的子进程,但在进程表中占了一个位置(slot)。子进程还会向父进程发送SIGCHLD信号,父进程调用wai...
2021-11-11 19:46:11
3188
原创 孤儿进程~
一般情况下,子进程是由父进程创建,而子进程和父进程的退出是无顺序的,两者 之间都不知道谁先退出。正常情况下父进程先结束会调用wait或者 waitpid 函数 等待子进程完成再退出,而一旦父进程不等待直接退出,则剩下的子进程会被 init(pid=1)进程接收,成会孤儿进程。(进程树中除了 init 都会有父进程)。给子进程设置sleep(10),保证父进程先退出。//孤儿进程#include<iostream>#include <std...
2021-11-10 23:04:25
909
原创 for循环创建子进程
目标用for循环创建三个子进程假想:父进程一次创建一个子进程,我们让它创建三次,然后就有了三个子进程;按照这个思路进行实现,相关代码如下。//循环创建n个子进程#include<iostream>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <unistd.h>using namesp.
2021-11-10 19:13:21
1986
原创 fork函数:创建子进程
fork函数创建子程序原理:关于fork函数函数几点说明:1.fork函数返回的两个值不是在一个进程中返回的,而是父子进程各返回一个值,其中父进程返回子进程的PID,子进程返回0;2.父子进程的执行顺序:谁先获得CPU谁先执行;3.父子进程执行的代码逻辑:父进程执行PID>0的逻辑,子进程执行PID等于0的逻辑;4.调用fork之后父子进程会一起并行执行,由原来一个进程变成两个进程。创建子进程代码如下://fork函数测试#include<iostream&.
2021-11-09 23:23:33
1562
原创 fcntl函数获得和设置文件的flag属性(读,写,追加等)
flag函数原型:int fcntl(int fd, int cmd, ... /* arg */ );追加操作步骤1.获取文件的flag属性,cmd:F_GETFL2.修改当前的flag属性(添加新属性);3.设置属性,cmd:F_SETFL代码如下:#include<iostream>#include<stdlib.h>#include<string.h>#include<sys/types.h>#include&
2021-11-08 17:05:21
542
原创 dup2函数:复制文件描述符示例
dup函数用于复制文件描述符,这样使得两个描述符指向同一个文件,这就类似于linux中的硬链接,此时内核会在内部维护一个计数为2,如果关闭其中一个不能真正的关闭文件,当计数为0时即两个文件描述符都被关闭,这个文件才真正被关闭。 dup2函数作用与dup函数一致,区别就是dup2函数可以指定要复制的文件描述符,dup2函数原型为:int dup2(int oldfd,int new fd)原理图如下: 为了验证oldfd和newfd...
2021-11-05 22:58:26
374
原创 使用st_mode判断文件权限和文件类型
st_mode属于stat结构体中的成员,使用它可以判断文件的类型以及文件的权限1.获取文件类型LINUX下一切接文件,共有7种文件类型 S_IFSOCK 0140000 socket //套接字文件 S_IFLNK 0120000 symbolic link //链接文件 S_IFREG 0100000 regular file //普通文件 S_IFBLK...
2021-11-04 22:34:21
1884
原创 IO函数代码示例(open,close,write,lseek,read)
本代码基于linux系统下的C/C++,相关函数原型介绍如下open():int open(const char *pathname, int flags, mode_t mode);参数分别为:文件所在路径,打开方式,文件的权限成功返回一个最小且未被占用的文件描述符;失败返回-1.close():int close(int fd);参数接收的是一个文件描述符.read():ssize_t read(int fd, void *buf, size_t...
2021-11-04 19:56:53
206
原创 makefile文件:编译工程文件
其本质是用来编译工程文件(内部可以理解为g++命令),用make命令,实现自动化编译。格式如下: 目标:依赖 (tab) 命令介绍makefile的最初级版本 当前目录下有 main.cpp temp.cpp temp1.cpp 执行vim makefile 然后输入指令main:main.cpp temp.cpp temp...
2021-11-02 22:50:17
924
原创 Linux下,c++创建并调用静态库和动态库
在C/C++中,使用的大多是系统写好的库文件我们用来调用。也可以使用自己建立的库;有两种库:静态库和动态库。首先来介绍静态库:事先创建.h文件,用来声明两个函数,分别用于静态库和动态库的调用。...
2021-11-01 21:32:42
3145
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人