注:pthread_exit或者return返回的指针所指向的内存单元必须是全局的或者是用malloc分配的,不能在线程函数的栈上分配,因为当其它线程得到这个返回指针时线程函数已经退出了
Linux 文件 IO 操作指的是在 Linux 系统上对文件进行读取和写入的操作。它是通过与文件系统交互来读取和写入文件中的数据。
早在LINUX2.2内核中。并不存在真正意义上的线程,当时Linux中常用的线程pthread实际上是通过进程来模拟的,也就是同过fork来创建“轻”进程,并且这种轻进程的线程也有个数的限制:最多只能有4096和此类线程同时运行。 2.4内核消除了个数上的限制,并且允许在系统运行中动态的调整进程数的上限,当时采用的是Linux Thread 线程库,它对应的线程模型是“一对一”,而线程的管理是在内核为的函数库中实现,这种线程得到了广泛的应用。但是它不与POSIX兼容。另外还有许多诸如信号处理,进程ID等方面的问题没有完全解决。 相似新的2.6内核中,进程调度通过重新的编写,删除了以前版本中的效率不高的算法,内核框架页也被重新编写。开始使用NPTL(Native POSIX Thread Library)线程库,这个线程库有以下几个目标: POSIX兼容,都处理结果和应用,底启动开销,低链接开销,与Linux Thread应用的二进制兼容,软硬件的可扩展能力,与C++集成等。 这一切是2.6的内核多线程机制更加完备。
在上一则发表的关于 Linux 的文章中,叙述了 Linux 的相关概念,其中就包括进程的资源,进程的状态,以及进程的属性等相关内容,在本则教程中,将着重叙述 Linux 进程管理的内容,其中就包括 Linux 进程的创建,进程的终止,进程的等待相关内容。
一、定义和理解 狭义定义:进程是正在运行的程序的实例。 广义定义:进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。 进程的概念主要有两点: 第一,进程是一个实体。每一个进程都有它自己的地址空间,一般情况下,包括文本区域、数据区域和堆栈区域。文本区域存储处理器执行的代码;数据区域存储变量和进程执行期间使用的动态分配的内存;堆栈区域存储着活动过程调用的指令和本地变量。 第二,进程是一个“执行中的程序”。程序是一个没有生命的实体,只有处理器赋予程序生命时,它才能成为一个活动的实体,我们称其为进程。
版权声明:本文为博主原创文章,转载请注明博客地址: https://blog.csdn.net/zy010101/article/details/83690667
Shell脚本 是一个脚本语言,用来自动执行我们指定的系统命令的。 通俗的讲,再shell脚本当中,我们会编写一些需要使用的系统命令于其中再运行这个叫本的时候,这些被编写进去的系统命令会按照书写的顺序及规则以此运行。
退出码是用来标识一个进程任务执行结果的情况。因为成功只有一种情况,而失败的情况很多,因此,一般情况下0表示执行成功,非0表示执行失败。非0的数字不同,所表示的错误不同。系统对于退出码一般都有着相应的文字藐视,当然我们也可以自定义,也可以直接使用系统给定的映射关系。(例如,strerror这个函数)
我们从实现的角度来看: 进程是一种数据结构,用描述程序运行的状态和系统变化的状态。
简单来讲,进程就是运行中的程序。更进一步,在用户空间中,进程是加载器根据程序头提供的信息将程序加载到内存并运行的实体。
函数中代码块执行的结果,如果我们后面的代码中需要用到,就需要函数返回我们执行的结果,就是需要返回值;
2018年的第一天,祝大家365天元气满满! 话不多说,先打响新年第一炮(不好意思,我又污了=.=) ***本系列内容仅用于技术分享,请勿对号入座*** 之前有讲过要分享一些云平台渗透的经验,其中最有意思的就属这个python shell了。 首先经过fuzzing发现了这样一个console口: 根据路径判断,这个应该是python的交互式shell,也就是我们平时在cmd命令行敲“python”之后出来的一个console,试了一下,果然是: 📷 但是执行系统命令的时候就返回不正常了,要么是0,要么是2
在一个标准的C语言程序中,最特殊的莫过于main函数了,而说到底它就是一个函数而已,仅仅因为它地位特殊拥有第一执行权力,换句话说,难道因为一个人是省长它就不是人类了?所以函数该有的它都应该有,那么函数还有什么呢?
1. 首先我们来看一个现象,当只有第一行代码时,编译是能通过的,但会报warning,当加了第二行代码时,编译无法通过,报error。 第一行代码能编过的原因是权限缩小,虽然ptr是可读可写的权限,但在指向常量字符串"hello world"之后,ptr的权限就变为了只读,所以如果仅仅修改一下权限,g++并不会报错,只是报个warning罢了,但当解引用ptr,将ptr指向的内容修改为"H"字符串后,编译器就会报错了,因为我们说ptr的权限是只读,因为常量字符串是不可修改的,你现在进行了ptr指向内容的修改,编译器则一定会报错。
1. 线程创建方法函数原型 : int pthread_create(pthread_t *tidp, const pthread_attr_t *attr, (void*)(*start_rtn)(void*), void *arg);
之前使用 引用 时 , 都是作为 右值 使用 , 引用只在 声明 的 同时 进行初始化时 , 才作为左值 ,
main函数的返回值用于说明程序的退出状态。如果返回0,则代表程序正常退出。返回其它数字的含义则由系统决定。通常,返回非零代表程序异常退出。
本文主要对Linux下的多线程进行一个入门的介绍,虽然是入门,但是十分详细,希望大家通过本文所述,对Linux多线程编程的概念有一定的了解。具体如下。
函数是指将一组语句的集合通过一个名字(函数名)封装起来,想要执行这个函数,只需要调用函数名即可
一般我们平时写main函数的话,一般都是写不带参数的比较多,而且也习惯了这样写;其实标准的形式写法,main函数是带两个参数的,这两个参数分别是:argc和argv,那么这两个参数是表示什么意思,怎么用呢?今天就给大家分享main函数里面这两个参数的使用,下面看到这样的写法,要明白这样写的意思哦!
通配符是由shell处理的(不是由所涉及到命令语句处理的,其实我们在shell各个命令中也没有发现有这些通配符介绍), 它只会出现在 命令的“参数”里(它不用在 命令名称里, 也不用在 操作符上)。当shell在“参数”中遇到了通配符时,shell会将其当作路径或文件名去在磁盘上搜寻可能的匹配:若符合要求的匹配存在,则进行代换(路径扩展);否则就将该通配符作为一个普通字符传递给“命令”,然后再由命令进行处理。总之,通配符 实际上就是一种shell实现的路径扩展功能。在 通配符被处理后, shell会先完成该命令的重组,然后再继续处理重组后的命令,直至执行该命令。
linux 中最常用的 IO 模型是同步 IO,在这个模型中,请求发出后应用程序会阻塞直到满足条件(阻塞 IO),或在不满足条件的情况下立即返回出错(非阻塞 IO),这样做的好处是程序在等待 IO 请求完成时不会占用 CPU。 POSIX 定义了异步 IO 应用程序接口(AIO API),linux 2.6 以上版本的内核也实现了内核级别的异步 IO 调用。 异步 IO 的基本思想是允许进程发起很多 IO 操作,而不用阻塞任何一个,也不用等待任何操作的完成,直到 IO 操作完成时,进程可以检索 IO 操作的结果。
fork常用法:1.一个父进程希望复制自己,使父子进程同时执行不同的代码段。2.一个进程要执行一个不同的程序。
描述:在进行shell脚本语言编写的时候,不仅要注意写的功能,更要注意他的美观以及通用性,还需要让其他参与运维的人都能看懂;
上一篇博客 【C++】C++ 引用详解 ③ ( 函数返回值不能是 “ 局部变量 “ 的引用或指针 | 函数内的 “ 局部变量 “ 的引用或指针做函数返回值无意义 ) 得出如下结论 :
System 系统调用的返回值 , 在不同的系统下是不同的 , 如 Windows , Linux , Mac 的系统调用返回值不同 ;
我们都知道PHP是单进程执行的,PHP处理多并发主要是依赖服务器或PHP-FPM的多进程及它们进程的复用,但PHP实现多进程也意义重大,尤其是在后台Cli模式下处理大量数据或运行后台DEMON守护进程时,多进程的优势不用多说。
一 线程间同步 同步:相互之间配合完成一件事情 互斥:保证访问共享资源的完整性(有你没我) POSIX 线程中同步:使用信号量实现 信号量 : 表示一类资源,它的值表示资源的个数 对资源访问: p操作(申请资源) [将资源的值 - 1] .... V操作(释放资源) [将资源的值 + 1] 1.定义信号量 sem_t sem ; 2.初始化信号量 int sem_init(sem_t *sem, int pshared, unsigned int value); 参数: @sem 信号量 @pshared 0:线程间使用 @value 初始化的信号量的值 返回值: 成功返回0,失败返回-1 3.P操作 int sem_wait(sem_t *sem); 4.V操作 int sem_post(sem_t *sem); 二 进程间通信(进程间数据交互) (1)传统进程间通信方式 [1]无名管道 [2]有名管道 [3]信号 (2)System 5 IPC对象进程间通信方式 [1]消息队列 [2]共享内存 [3]信号灯集 (3)socket通信 (4)Android系统中增加Binder进程间通信方式 Linux 支持以上所有进程间通信方式 三 管道进程间通信 (1)无名管道 特点: 只能用于具有亲缘关系进程间通信(具有亲缘关系的进程具有数据拷贝动作(复制父进程创建子进程)) int pipe(int pipefd[2]); 功能:创建一个无名管道 参数: @pipefd 获取操作无名管道的文件描述符 pipefd[0]:读无名管道 pipefd[1]:写无名管道 返回值: 成功返回0,失败返回-1 (2)管道读写规则 读端存在 ,写管道 ---->只要管道没有满,都可以写入数据到管道 读端不存在,写管道 ---->此时写管道没有意义,操作系统会发送SIGPIPE杀死写管道的进程 写端存在, 读管道 ---->此时管道中读取数据,管道中没有数据,读阻塞 写端不存在,读管道 ---->此时管道中读取数据,管道中没有数据,此时不阻塞,立即返回,返回值0 (3)有名管道 特点:可以用于任意进程间通信,它是一种特殊的文件,在文件系统存在名字, 而文件中存放的数据是在内核空间,而不是在磁盘上 1.创建一个有名管道文件 int mkfifo(const char *pathname, mode_t mode); @pathname 有名管道存在的路径 @mode 有名管道的权限 返回值: 成功返回0,失败返回-1 2.打开有名管道文件 open 如果有名管道的一端以只读的方式打开,会阻塞,直到另一端以写(只写或读写)的方式打开 如果有名管道的一端以只写的方式打开,会阻塞,直到另一端以读(只读或读写)的方式打开 3.读写操作 read /write 4.关闭管道文件 close(fd); 四 信号 信号是异步进程间通信方式 进程对信号的响应方式: <1>忽略 SIGKILL 和 SIGSTOP 不能忽略 <2>捕捉 当进程收到信号,此时执行的信号处理函数 <3>默认 大部分信号对进程的默认操作方式都是杀死进程 子进程状态发生改变的时候,操作系统向父进程发送SIGCHLD,默认对它处理方式是忽略 typedef void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t handler); 功能:设置进程对信号处理方式 参数: @signum 信号的编号 @handler SIG_IGN : 忽略信号 SIG_DFL : 使用默认处理方式 函数名 : 捕捉方式处理 返回值: 成功返回handler,失败返回SIG_ERR 练习: 如何进行不阻塞,不轮训方式回收僵尸态子进程 2.在进程中设置一个定时器 unsigned int alarm(unsigned int seconds); 参数: @seconds 定时的时间,以秒为单位 注意: 一旦定时时间完成,操作系统就会向进程发送SIGALRM信号 A进程: 读文件,写管道 A进程结束条件:文件没有数据可读 B进程: 读管道,写文件 B进程结束条件:在
Linux文件操作 Linux中,一切皆文件(网络设备除外)。 硬件设备也“是”文件,通过文件来使用设备。 目录(文件夹)也是一种文件。 Linux文件的结构 📷 root:该目录为系统管理员(也称作超级管理员)的用户主目录。 bin:bin是Binary的缩写,这个目录存放着最经常使用的命令。 boot:这里存放的是启动Linux时使用的一些核心文件,包括一些连接文件和镜像文件。 deb:deb是Device(设备)的缩写,该目录下存放的是Linux的外部设备,在Linu
地址空间是进程能看到的资源窗口:一个进程能看到代码区、共享区、内核区、堆栈区,大部分的资源都是在地址空间上看到的
楼主本来是要继续写服务器并发的,但是后续的服务器相关点都和进程线程联系在一起,所以先把进程线程相关内容写完吧! 这次只写进程线程的概述,实际操作后续博文逐一代码实现。 进程同步or进程通信/线程同步or线程通信? 这两组概念迷惑我至今,网上和书籍对这个的描述也是爱用啥用啥的感觉,今天又重新理了一遍。 什么是同步:同步就是数据保持一致,无论是进程还是线程,都是实现了代码执行流程的分支,多个分支同时进行。多个分支互不干扰,但是又有些数据需要共享,让这些数据对所有分支保持一致即为同步。 什么是
一,复习 # 什么是函数:具体特定功能的代码块 - 特定功能代码块作为一个整体,并给该整体命名,就是函数 # 函数的优点: # 1.减少代码的冗余 # 2.结构清晰,可读性强 # 3.具有复用性,开发效率高,维护成本低 # 如何定义一个函数:用def关键词来声明函数 ''' def fn(参数列表): 函数体 return 函数的返回值 ''' # -- 定义函数时,函数体不会被执行 | 函数必须先定义后使用 # 函数的四部分: # 函数名:存放着函数的地址,是调用函数
我们常见的计算机,如笔记本。我们不常见的计算机,如服务器,大部分都遵守冯诺依曼体系。
1.线程的概念 在linux操作系统下,线程的本质任然是进程。是轻量级的进程(light weight process)简称LWP,但线程与进程还是有很多的区别。
由于“*”的优先级低于“()”的优先级,因而pfun首先和后面的“()”结合,也就意味着,pfun是一个函数。即:int *(pfun(int, int));
进一步讲,进程是在用户空间中,加载器根据程序头提供的信息,将程序加载到内存并运行的实体。
说到shell通配符(wildcard),大家在使用时候会经常用到。下面是一个实例:
在用linux命令时候,我们可以一行执行多条命令或者有条件的执行下一条命令,下面我们讲解一下linux命令分号&&和&,|和||的用法
最近想要实现通过脚本循环再Linux下运行shell命令,经过探索发现使用Python语言有几种解决方案,在此简单记录。
先看一个例子,@property。被@property修饰的成员函数,将变为一个描述符。这是最简单的创建描述符的方式。 class Foo: @property def attr(self): print('getting attr') return 'attr value' def bar(self): pass foo = Foo() 上面这个例子中, attr 是类 Foo 的一个成员函数,可通过语句 foo.attr() 被调用。 但当它被 @property 修饰后
子进程 在被创建后,共享的是 父进程 的代码,如果想实现自己的逻辑就需要再额外编写代码,为了能让 子进程 执行其他任务,可以把当前 子进程 的程序替换为目标程序,此时需要用到 Linux 进程程序替换相关知识
最近查资料时,偶然在youtobe看到了华盛顿大学自然科学与工程一位老师 关于 Procedure & Stacks 的课程,深入讲解了基于Stack的过程调用,展示了应用级别和寄存器级别的处理过程,演示非常形象,受益良多。以下是课程重点及视频链接,可以自行翻墙观看。
一、课程介绍 UNIX/Linux环境C语言,借助学习操作系统的接口的方法来学习、理解操作系统的 运行机制以及一些网络协议 C/C++、数据结构和算法 与平台无关,重点是算法逻辑 Uinx/Linux/Android/IOS 平台相关,系统接口 嵌入式/驱动/移植 硬件相关,硬件接口
使学生理解Linux中进程控制块的数据结构,Linux进程的创建、执行、终止、等待以及监控方法。并重点掌握fork函数的使用以及exec系列函数。
一般来说,项目开发过程中,代码编写占开发总时间的40%,剩下的时间基本就是自测和联调的过程。程序出错很正常,关键是如何迅速的去定位它,修掉它。本文将介绍自己程序调试的一些常用方法,这边我以golang为例,总结为望问切闻---debug四部曲。
我们通常在进行一些功能处理的过程中,需要执行一行或者多行代码来完成整个业务流程的处理,如:
领取专属 10元无门槛券
手把手带您无忧上云