精华内容
下载资源
问答
  • 所以经常在SIGCHLD处理程序中调用waitpid函数,这样就可以期望他能立即返回,但是如果在执行SIGCHLD处理程序期间又有子进程终止,因为unix不对信号排队,如果多于一个子进程终止,则会导致信号丢失,在这种情况下...
    当已经有SIGCHLD信号时,我们调用waitpid是可以立即返回的。所以经常在SIGCHLD处理程序中调用waitpid函数,这样就可以期望他总能立即返回,但是如果在执行SIGCHLD处理程序期间又有子进程终止,因为unix不对信号排队,如果多于一个子进程终止,则会导致信号丢失,在这种情况下,如果只调用一次waitpid就会导致僵死进程的产生,可以采取while(waitpid(-1,0,WNOHANG)>0);来避免这个问题。还有一种方式是将options设置为WNOHANG在调用waitpid也会立即返回。
    
    展开全文
  • linux线程共享和进程内存的关系

    千次阅读 2014-12-03 17:06:44
    最近在了解线程方面的内容,觉得对线程共享、线程全局变量、线程局部变量的处理方式有点迷糊,下面从进程和线程的角度分析了内存情况,如有不对之处,各位老鸟请留言加以指正。 进程内存分析: 1、栈区...

    最近在了解线程方面的内容,总觉得对线程共享、线程全局变量、线程局部变量的处理方式有点迷糊,下面从进程和线程的角度分析了内存情况,如有不对之处,各位老鸟请留言加以指正。

    进程内存分析:

    1、栈区(stack)— 由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。

    2、堆区(heap) — 一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。

    3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后由系统释放。

    4、文字常量区   —常量字符串就是放在这里的。程序结束后由系统释放。

    5、程序代码区—存放函数体的二进制代码。

    线程共享与私有数据

    线程共享的环境包括:进程代码段、进程的公有数据(利用这些共享的数据,线程很容易的实现相互之间的通讯)、进程打开的文件描述符、信号的处理器、进程的当前目录和进程用户ID与进程组ID。 进程拥有这许多共性的同时,还拥有自己的个性。有了这些个性,线程才能实现并发性。这些个性包括:

    1.线程ID 每个线程都有自己的线程ID,这个ID在本进程中是唯一的。进程用此来标 识线程。

    2.寄存器组的值 由于线程间是并发运行的,每个线程有自己不同的运行线索,当从一个线 程切换到另一个线程上时,必须将原有的线程的寄存器集合的状态保存,以便将来该线程在被重新切换到时能得以恢复。

    3.线程的栈 栈是保证线程独立运行所必须的。 线程函数可以调用函数,而被调用函数中又是可以层层嵌套的,所以线程必须拥有自己的函数堆栈,使得函数调用可以正常执行,不受其他线程的影 响。

    4.错误返回码 由于同一个进程中有很多个线程在同时运行,可能某个线程进行系统调用 后设置了errno值,而在该线程还没有处理这个错误,另外一个线程就在此时 被调度器投入运行,这样错误值就有可能被修改。 所以,不同的线程应该拥有自己的错误返回码变量。

    5.线程的信号屏蔽码 由于每个线程所感兴趣的信号不同,所以线程的信号屏蔽码应该由线程自 己管理。但所有的线程都共享同样的信号处理器。

    6.线程的优先级 由于线程需要像进程那样能够被调度,那么就必须要有可供调度使用的参 数,这个参数就是线程的优先级。

    线程共享了进程的那些区域

    堆: 是大家共有的空间,分全局堆和局部堆。全局堆就是所有没有分配的空间,局部堆就是用户分配的空间。堆在操作系统对进程初始化的时候分配,运行过程中也可以向系统要额外的堆,但是记得用完了要还给操作系统,要不然就是内存泄漏。


    栈:是个线程独有的,保存其运行状态和局部自动变量的。栈在线程开始的时候初始化,每个线程的栈互相独立,因此,栈是 thread safe的。每个C ++对象的数据成员也存在在栈中,每个函数都有自己的栈,栈被用来在函数之间传递参数。操作系统在切换线程的时候会自动的切换栈,就是切换 SS/ESP寄存器。栈空间不需要在高级语言里面显式的分配和释放。

     

    最后结合以上分析,得出内存中存在共享的地方(下图红色部分):

        有关进程的参数与环境区是共享的;

        堆区是共享的;

        全局区(静态区)共享的;

        文字常量区共享;

        代码区共享。

     

    展开全文
  • 线程

    2020-02-13 21:15:05
    文章目录线程概述线程的特点线程的共享资源和私有资源基于linux线程操作线程的创建——pthread_create线程的回收——pthread_join线程结束——pthread_exit线程间通信线程通信——同步信号量(灯)线程间通信...

    线程概述

    线程是操作系统能够进行运算调度的最小单位。它包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。

    线程的特点

    1)轻型实体
    线程中的实体基本上不用有系统资源,只有一点必不可少的、能保证独立运行的资源。
    线程的实体包括程序、数据、TCB。线程是动态概念,它的动态特性由线程控制块TCB描述。

    TCB包括以下信息:

    • 线程状态
    • 当线程不运行时,被保存的现场资源。
    • 一组执行堆栈
    • 存放每一个线程的局部变量主存区。
    • 访问同一进程中的主存和其他资源。

    【TCB内容:用于指示被执行指令序列的程序计数器、保留局部变量、少数状态参数和返回地址等的一组寄存器和堆栈】
    2)独立调度和分派的基本单位
    在多线程OS中,线程是能够独立运行的基本单位,因而也是独立调度和分派的基本单位。由于线程很“轻”,故线程的切换非常迅速且开销小(同一进程中)。
    3)可并发执行
    在一个进程中的多个线程之间,可以并发执行,甚至允许在一个进程中所有的线程都能并发允许;同样,不同进程中的线程也能并发执行,充分利用和发挥了处理机与外围设备并行工作的能力。
    4)共享进程资源
    在同一进程中的各个线程,都可以共享该进程所拥有的资源,这首先表现在:所有线程都具有相同的地址空间(进程的地址空间),这意味着,线程可以访问该地址空间的每一个虚地址;此外,还可以访问进程所拥有的已打开文件、定时器、信号量机构等。由于同一个进程内的线程共享内存和文件,所以线程之间互相通信不必调用内核。
    5)Linux中不区分进程、线程
    6)使用多线程的好处
    使用多线程大大提高了任务切换的效率,避免了额外的TLB&cache的刷新

    线程的共享资源和私有资源

    共享资源 私有资源
    可执行的指令 线程ID(TID)
    静态数据 PC(程序计数器)和相关寄存器
    进程中打开的文件描述符 堆栈
    当前工作目录 错误号
    用户ID 优先级
    用户组ID 执行状态和属性

    基于linux的线程操作

    在Linux线程库pthread中提供了创建线程、回收线程、结束线程的基本操作,同时,线程的同步和互斥机制也是重点。

    线程的创建——pthread_create

    int pthread_create(pthread_t * thread ,const pthread_attr_t * attr,void * ( * routine)(void * ),void * arg);

    • 头文件 #include<pthread.h>
    • 成功时返回0,失败时返回错误码
    • thread 线程对象
    • attr 线程属性,NULL代表默认属性
    • routine 线程执行的函数
    • arg 传递给routine的参数,参数是void * ,注意传递参数格式
      pthread_t pthread_self(void) 查看自己的TID

    线程的回收——pthread_join

    int pthread_join(pthread_t thread , void ** retval);

    • 头文件include<pthread.h>
    • 成功时返回0,失败时返回错误码
    • thread 要回收的线程对象
    • 调用线程阻塞知道thread结束
    • *retval 接受线程thread的返回值

    线程的结束——pthread_exit

    void pthread_exit(void * retval);

    • 头文件 #include<pthread.h>
    • 结束当前线程
    • retval可被其他线程通过pthread_join获取
    • 线程私有资源被释放

    线程间通信

    线程共享同一进程的地址空间,所以线程间通信很容易【通过全局变量交换数据即可】,在多个线程通信时,访问共享数据的时候需要用到同步和互斥机制。

    线程通信——同步

    同步指的是多个任务按照约定的先后次序相互配合完成一件事情,线程通信的同步机制由信号量来决定线程是继续运行还是阻塞等待

    信号量(灯)

    信号量代表某一类资源,某值表示系统中该资源的数量.
    信号量是一个受保护的变量,只能通过三种操作来访问:
    1)初始化
    2)P操作(申请资源)【消费者】
    3)V操作(释放资源)【生产者】

    P操作含义如下:

    if(信号量的值大于0{
    	申请资源的任务继续运行;
    	信号量的值减一;
    }
    else
    {
    	申请资源的任务阻塞;
    }
    

    V操作含义如下:

    信号量的值加一;
    if(有任务在等待资源)
    {
    唤醒等待的任务,让其继续运行;
    }
    

    Posix 信号量,posix中定义了两类信号量:

    • 无名信号量(基于内存的信号量)
    • 有名信号量

    1)信号量初始化——sem_init
    int sem_init(sem_t * sem , int pshared ,unsigned int val);

    • 头文件 #include<semaphore.h>
    • 成功时返回0,失败时返回EOF
    • sem 指向要初始化的信号量对象
    • pshared 0代表线程间 1代表进程间
    • val 信号量初值

    2)信号量的P/V操作
    int sem_wait(sem_t * sem); ——P操作
    int sem_post(sem_t * sem); ——V操作

    • 头文件 #include<semaphore.h>
    • 成功时返回0,失败时返回EOF
    • sem 指向要P/V操作的信号量对象

    线程间通信——互斥

    临界资源: 一次只允许一个任务(线程、进程)访问的共享资源
    临界区: 临界区指的是一个访问共用资源(例如:共用设备或是共用存储器)的程序片段,而这些共用资源又无法同时被多个线程访问。当有线程进入临界区段时,其他线程或是进程必须等待,有一些同步的机制必须在临界区段的进入点与离开点实现,以确保这些共用资源是被互斥获得使用。
    互斥机制通过mutex互斥锁实现,任务访问临界资源前申请锁,访问完后释放锁。

    互斥锁的初始化——pthread_mutex_init

    在使用互斥锁之前,需要对互斥锁进行初始化。
    int pthread_mutex_init(pthread_mutex_t * mutex, const pthread_mutexattr_t * attr);

    • 头文件 #include<pthread.h>
    • 成功时返回0,失败返回错误码
    • mutex 指向要初始化的互斥锁对象
    • attr 互斥锁属性,NULL代表缺省属性

    申请锁——pthread_mutex_lock

    int pthread_mutex_lock(pthread_mutex_t * mutex);

    • 头文件 #include<pthread.h>
    • 成功时返回0,失败返回错误码
    • mutex 指向要上锁的对象
    • 如果无法获得锁,任务阻塞

    释放锁——pthread_mutex_unlock

    int pthread_mutex_unlock(pthread_mutex_t * mutex);

    • 头文件 #include<pthread.h>
    • 成功时返回0,失败返回错误码
    • mutex 指向要释放锁的对象
    • 执行完临界区要及时释放锁

    总结

    同步机制与互斥机制还不熟练,需要加深!!!

    展开全文
  • Linux系统开发

    2020-03-30 09:48:27
    先列一下Linux系统开发要掌握的知识,后续的文章中,会一 一讲解。...常规Linux编程知识文件IO文件与目录操作标准IO库进程控制线程编程高级IO进程间通信数据库串口编程网络编程结束Linux系统开发...

    先列一下Linux系统开发要掌握的知识,后续有时间再一一来讲。
    欢迎关注我的微信公众号:fensnote

    Linux系统开发会用到什么?

    C语言基础

    Linux系统内核是C语言编写的,所以,Linux系统开发可能会和很多系统API打交道,需要掌握C语言基础,C语言是Linux最基础的开发语言,当然也可以用C++。一般做与系统交互的模块时,用C语言多一些,做上层业务应用时,为了开发效率,会使用C++来开发,毕竟C++是面向对象的开发语言,适合大型项目的开发,方便模块化,代码复用率高。

    shell脚本

    shell脚本,也就是使用Linux系统下的一系列命令,有机组合在一起,而完成预期的功能。Linux设计思想是“小即是美”,这一思想是shell脚本编程的完美体现。每个命令只完成一种功能,不同的命令组合在一起,却可以实现复杂的功能。做Linux下开发,免不了要与脚本打交道(比如测试、分析数据等)。

    学会使用Makefile

    Makefile是Linux程序开发时必不可少的编译管理脚本,这个里面东西也很多,不过刚开始可以简单看看,够用就行,随着项目的越做越大,代码文件与目录越来越复杂,这时候的Makefile可能就会复杂一些,牵扯到不同目录的Makefile的相互调用或者协调。
    比如嵌入式系统中,一般不止一个应用程序,可能会有多个程序,在整体编译时,会包括如下内容:

    1. 各个应用程序模块的编译(需要判断是否编译成功,出现编译失败的情况停下来,抛出错误信息)
    2. 应用程序打包(做成压缩包或者分区镜像)
    3. 默认配置文件打包
    4. uboot、内核、文件系统、应用程序整体打包成一个镜像文件,大小对应flash分区的大小(大小不足需要填充空数据,保证与分区对应)。
    5. 自动版本管理,在编译完成,打包完成后,可以通过脚本来自动根据时间生成版本号。

    这些东西做起来其实挺复杂的,需要Makefile与shell脚本搭配完成。

    常规Linux系统编程知识都有什么?哪些常用?哪些不常用?

    常规Linux编程知识

    文件IO

    比较常用
    Linux系统下,所有的资源都是以文件的形式访问的,设备被抽象为设备文件,放于/dev目录下。
    基本的访问函数:

    函数名 简介 一般怎么用
    open 打开设备文件 访问设备文件,首先要先打开设备
    close 关闭设备文件 文件访问结束后,需要调用该接口,如果不关闭,会造fb耗尽
    read 读取数据 读取数据,可以是文本文件内容,也可以是摄像头数据等
    write 写入数据 向设备写数据,比如串口通信时,可以用write发送数据
    ioctl IO操作函数 该函数功能比较多,被称作杂物箱~,可以读、写数据,做驱动的同学应该很了解
    fcntl 属性设置函数 对已经打开的设备,设置属性,比如可以设置串口读数据的阻塞和非阻塞属性
    lseek 改变偏移量 一般用于对已打开的文件读写位置的偏移量修改
    文件与目录操作

    常用
    系统编程少不了文件与目录的访问,比如你要读取某个目录下的所有文件名字,或者修改文件名、修改目录,移动文件等等。

    函数名 简介 一般怎么用
    stat、 fstat 、lstat 获取文件状态 可以获取到文件的创建、访问时间,文件大小等
    access 检测文件属性 常用于判断文件是否存在
    chmod 修改文件权限 一般涉及到文件访问权限修改时,会用到,比如增加可执行权限
    mkdir 创建目录 一般在程序里判断到需要用到的目录不存在时,用此函数创建
    rmdir 删除目录 需要删除目录时使用,一般很少用到
    opendir 打开目录 在读取目录信息之前,需要先打开目录(类中与文件访问)
    readdir 读取目录内容 在检索文件时,会用到,读取目录下文件列表
    closedir 关闭目录 在读取完成后,记得关闭目录
    sync 同步数据到磁盘 这个函数一般在修改文件,写入数据后调用,让系统把数据同步到磁盘
    标准IO库

    比较常用
    所谓标准IO库,其实是C语言里的文件IO,另外这里面的IO与前面提到的“文件IO”在文件的读写上有个区别,标准IO是有缓存的,而Linux系统的文件IO函数是无缓存的。
    主要是文件操作函数:

    函数名 简介 一般怎么用
    fopen 打开文件 放文件文件前先调用fopen获取文件句柄
    fclose 关闭文件 文件访问结束后,记得关闭文件,否则造成内存泄露
    fread 读取文件 读取文件数据
    fseek 修改文件读写位置 用于修改文件读写的位置偏移量
    进程控制

    一般
    如果你不使用多进程编程的话,这一项可能就用的不多,我的代码里用的也不是太多。
    这个知识点主要是进程的创建、子进程管理、进程退出资源释放等等。

    线程编程

    比较常用
    上了系统,一般跑的任务就会比较多,线程是比较常用的,一般可以分为两种,一种是长时间运行的任务,一种是执行完任务自行退出。现在C++11已经支持了线程,使用起来非常方便。之前没有C++11时,为了方便使用,都是对pthrea_簇函数进行了二次封装。

    高级IO

    常用
    可能你会比较奇怪,为什么这么多“IO”相关的东西:文件IO、标准文件IO、高级IO!
    是的,这里的IO比较多,前两个“IO”还有点相似,这个高级IO和前面两个有点不太一样。
    高级IO里主要是讲的IO操作的方式:阻塞、非阻塞控制,最主要的是通过select和poll实现IO多路复用,这样可以实现程序的异步执行。现在用的比较多的Nginx,就是使用的epoll模型,实现的高并发。

    进程间通信

    非常常用
    一般在linux系统下面,既然是系统,就不止一个应用程序在运行,那多个应用程序,就会需要数据交互,那么,就用到了进程间通信,进程间通信有许多开源的工具(比如DBUS),这里简单介绍一下系统里提供的通信方式:

    名称 简介
    管道 一般用于父子进程间通信,有名管道可以跨程序
    消息队列 消息队列可以分类型,适用于数据量小的,简单通信
    信号量 PV操作,用于同步,可以与共享内存搭配用,写完数据,告诉另一个线程可以读取了
    共享内存 适用于大数据量的传输
    socket socke不仅是网络通信的接口,也可以是本地进程间通信(UNIX socke),这种方式很常用
    数据库

    常用
    如果是存储配置参数,我不太推荐用数据库,用json就挺好。数据一般用于存储比较规则的数据,这样方便数据的管理。在嵌入式系统,用的比较多的是sqlite数据库。

    串口编程

    比较常用
    在Linux下,特别是做嵌入式系统,这个可能是少不了的,比较常用。其实串口编程也很简单,可能200行代码就可以把串口通信建立起来了。应用层的数据通信,就是使用write、和read函数操作,但是如果想做的比较好一些,就需要花点时间去做个软件框架,比如利用前面提到的select实现异步操作(后面文章会介绍实现方式以及串口的封装)。

    网络编程

    超级常用
    相信现在的嵌入式设备基本上都需要网络通信功能,所以,网络编程自然是非常常用的。特备是现在物联网的发展,万物互联。Linux下的网络编程,有一系列的API函数,挺多的,参数配置也比较多,刚开始会让人很头疼,不知道哪个参数设置个什么值合适(我们都是慢慢试错试出来的)。这个也不用担心,我后面会给大家分享出来我用C++封装好的网络通信库,包括TCP、UPD、UDP组播、域套接字(本地)等的封装。

    结束语

    后续准备按照今天列出的这几项内容,在后面的文章一一介绍,欢迎大家关注跟进。

    微信公众号:
    在这里插入图片描述

    展开全文
  • 程序简单来说类似一个多线程下载器,开了1024个线程,然后并发去服务器读取一个大文件的某一块,读取完成后,文件合并要按照顺序写...//等待上一个线程结束 write(fd,th_d->file,file - th_d->file);//写文件 }
  • * 开启应用程序,系统给应用程序创建一个Linux进程,开启一个主线程,所有的组件都运行在这个进程里...* 线程线程运行在进程中,进程结束线程也就结束 转载于:https://www.cnblogs.com/loaderman/p/6416138.html...
  • 选择退出时,结束进程或线程,关闭程序。 服务器:为每个客户连接创建一个进程或线程,处理客户信息,当有新客户加入或有客户退出时,将客户加入或退出信息发送给每个客户端;当收到某客户的群发信息时,将信息转发...
  • Unix/Linux编程实践一书 p440 14.5.2,介绍了使用条件变量进行线程同步。 程序是开两个线程分别统计两个文件的字数,都统计完后,主线程得出文字数。 现在想要一个线程统计完成之后立即能够通知主线程,从而主线...
  • Qt网络五子棋游戏

    热门讨论 2013-12-08 00:04:04
    描述:Qt学习结束后的一个总结性的练习项目,实现两个客户端(邀请和接受方)联机游戏,其它的客户端观看的功能。代码量1200行。服务器为linux系统编程实现共370行,客户端Qt实现共740行。主要用到的知识点:线程...
  • FAQ(持续更新)

    2021-01-08 12:27:51
    Linux系统为例: ~~~sh $ git clone https://github.com/sogou/workflow $ cd workflow $ make $ cd tutorial $ make ~~~ 然后就可以愉快的运行示例了。每个示例都有对应的文档讲解。如果需要用到kafka协议&...
  • 3.1.5 常用的Linux命令 3.1.6 C中变量的存储类型有哪些? 3.1.7 动态规划的本质 3.1.8 实践中如何优化MySQL? 3.1.9 什么情况下设置了索引但无法使用? 3.2.0 SQL语句的优化 3.2.1 数据库索引的底层实现原理和...
  • 操作系统(内存管理)

    热门讨论 2009-09-20 12:55:25
    文将对 Linux™ 程序员可以使用的内存管理技术进行概述,虽然关注的重点是 C 语言,但同样也适用于其他语言。文中将为您提供如何管理内存的细节,然后将进一步展示如何手工管理内存,如何使用引用计数或者内存池来半...
  • Scrapy入门学习初步览 解决Windows下pip install scrapy 出错 及 pycharm使用安利 scrapy入门学习初步探索之数据保存 爬取通过ajax动态加载的页面(实时监控华尔街见闻资讯与快讯) Python爬虫:人人影视追剧脚本 ...
  • Python Cookbook

    2013-07-31 22:33:26
    1.19 检查字符串中的结束标记 39 1.20 使用Unicode来处理国际化文本 40 1.21 在Unicode和普通字符串之间转换 43 1.22 在标准输出中打印Unicode字符 45 1.23 对Unicode数据编码并用于XML和HTML 46 1.24 让某些...
  • 用户一堆后续操作,可能浪费了很多时间,也可能是用户电脑太卡或其它原因,,同时web的的线程,js倒计后,指向 www.newurl.com CPU时间片,代码块间轮循时,不可能保证大家都是平等的,有的多轮到些,有的少些,多核下,优明显...
  • 易语言5.1 相对于易语言5.0更新说明:  支持静态链接其它编程语言(如C/C++、汇编等)编译生成的静态库(.LIB或.OBJ),但仅限于COFF格式,支持cdecl和stdcall两种函数调用约定。  使用说明如下:函数声明和调用...
  • 这一点貌似在 Linux 和 Mac OS X 下不用操心,在 Windows 下有可能遇到需要安装驱动的情况,确认这一点可以右键「计算机」-「属性」,到「设备管理器」里查看相关设备上是否有黄色感叹号或问号,如果没有就说明驱动...
  • Android 上百实例源码分析以及开源分析 集合打包4

    千次下载 热门讨论 2012-07-10 21:54:03
    Droid Wall - Android Firewall 是一个类似于 Linux 下的 iptables 的 Android 手机防火墙软件,允许你限制某些应用访问数据网络,包括 2G/3G 以及 Wi-Fi。 项目共六个文件: Api 包含共享的编程接口。处理所有ip...

空空如也

空空如也

1
收藏数 20
精华内容 8
关键字:

linux总线程结束

linux 订阅