购买

¥ 25.0

加入VIP
  • 专属下载特权
  • 现金文档折扣购买
  • VIP免费专区
  • 千万文档免费下载

上传资料

关闭

关闭

关闭

封号提示

内容

首页 C语言-进程间通信

C语言-进程间通信.ppt

C语言-进程间通信

精品课件库
2019-06-16 0人阅读 举报 0 0 暂无简介

简介:本文档为《C语言-进程间通信ppt》,可适用于IT/计算机领域

C语言进程间通信上海****通信技术有限公司MrJim(seniordbasinacom)培训大纲基础概念进程产生的方式进程间通信和同步Linux下的线程同步与互斥的概念临界资源与临界区临界资源:一段时间内仅允许一个进程使用的资源称为临界资源。 如:打印机、共享变量。临界区:进程中访问临界资源的那段代码称为临界区又称临界段。同类临界区:所有与同一临界资源相关联的临界区。同步与互斥同步:多个相互合作的进程在一些关键点上可能需要互相等待或互相交换信息这种相互制约关系称为进程同步。互斥:当一个进程正在使用某资源时其他希望使用该资源的进程必须等待当该进程用完资源并释放后才允许其他进程去访问此资源我们称进程之间的这种相互制约关系为互斥。   信号量说明:信号量就是操作系统中所用到的PV原语广泛用于进程或线程间的同步与互斥。本质上是一个非负的整数计数器被用来控制对公共资源的访问。PV原语是对整数计数器信号量sem的操作。一次P操作使sem减一而一次V操作使sem加一。进程或线程根据信号量的值来判断是否对公共资源具有访问权限当信号量sem的值大于等于零时该进程或线程具有公共资源的访问权限相反当信号量sem的值小于零时该进程或线程就将阻塞直到信号量sem的值大于等于为止PV原语主要用于进程或线程间的同步和互斥两种典型情况。如用于互斥几个进程或线程往往只设置一个信号量sem当信号量用于同步操作时往往会设置多个信号量并安排不同的初始值来实现他们之间的顺序执行P操作和V操作是不可中断的程序段称为原语.P,V原语中P是荷兰语Passeren,相当于英文的pass,V是荷兰语的Verhoog,相当于increment。信号量信号量的定义信号量由两个成员(sq)组成其中s是一个具有非负初值的整型变量q是一个初始状态为空的队列。又称信号灯。除信号量的初值外信号量的值仅能由P操作(又称为wait操作)和V操作(又称为signal操作)改变。信号量的物理含义信号量中的整型变量S表示系统中某类资源的数目。当其值大于时表示系统中当前可用资源的数目当其值小于时其绝对值表示系统中因请求该类资源而被阻塞的进程数目。P操作设S为一个信号量P(S)执行时主要完成下述动作:S=S-if(S<){设置进程状态为等待将进程放入信号量等待队列转调度程序}V操作V(S)执行时主要完成下述动作:S=S+if(S≤){将信号量等待队列中的第一个进程移出设置其状态为就绪状态并插入就绪队列然后再返回原进程继续执行}注意P操作可能阻塞执行进程而V操作可以唤醒其他进程。P、V操作在封锁中断的情况下执行即一个进程在信号量上操作时不会有别的进程同时修改该信号量。也就是说P、V操作是原语。培训大纲程序、进程和线程的概念进程产生的方式进程间通信和同步Linux下的线程进程号每个进程在初始化的时候系统都分配了一个ID号用于标识此进程。在Linux中进程号是唯一的系统可以用这个值来表示一个进程描述进程的ID号通常叫做PID,即进程ID(processid)。PID的变量类型是pidt。getpid()函数介绍#include<systypesh>#include<unistdh>pidtgetpid()pidtgetppid()进程复制fork()产生进程的方式比较多fork()是其中的一种方式。fork()函数以父进程为蓝本复制一个进程其ID号和父进程号不同。在Linux环境中fork()是以写复制方式实现的只有内存等与父进程不同其它与父进程共享只有在父进程或者子进程进行了修改后才重新生成一份。fork()函数介绍fork()的原型如下当成功时fork()函数的返回值是进程的ID失败则返回#include<systypesh>#include<unistdh>pidtfork(void)fork()的特点是执行一次返回两次。父进程和子进程中返回的是不同的值。父进程返回的是子进程的ID号而子进程返回的是。system()方式system()函数调用shell的外部命令在当前进程中开始另一个进程。system()函数介绍system()函数调用”binshccommand”执行特定的命令阻塞当前进程直到command命令执行完毕。System()的原型如下:#include<stdlibh>intsystem(constchar*command)执行system()函数时会调用fork、execve、waitpid等函数其中任意一个调用失败将导致system()函数调用失败。System()函数的返回值如下:失败返回当sh不能执行时返回成功返回进程状态值进程执行exec在使用fork()函数和system()函数的时候,系统中都会建立一个新的进程,执行调用者的操作,而原来的进程还会存在,直到用户显示的退出而exec()函数与之前的fork()和system()函数不同,exec()函数会用新进程代替原有的进程,系统会从新的进程运行,新的进程的PID值会与原来进程的PID值相同.exec()函数其原型如下:#include<unistdh>intexecve(constchar*path,char*constargv)与fork()函数不同exec()函数执行成功后不会返回这是因为执行的新程序已经占用了当前进程的空间和资源这些资源包括代码段、数据段和堆栈段等它们都已经被新的内容取代而进程的ID等标识性的信息仍然是原来的东西即exec()函数在原来进程的壳上运行了自己的程序只有程序调用失败了系统才会返回所有用户态进程的产生进程init在Linux系统中所有的进程都是由父子或者堂兄关系的没有哪个进程与其它进程完全独立。除了初始进程init,系统中每个进程都有一个父进程新的进程不是被全新得创建通常是从一个原有的进程进行复制或者克隆的。Linux操作系统下的每一个进程都有一个父进程或者兄弟进程并且有自己的子进程.可以在Linux下使用命令pstree来查看系统中运行的进程之间的关系如下所示.可以看出init进程是所有进程的祖先其他的进程都是由init进程直接或者间接fork()出来的。培训大纲程序、进程和线程的概念进程产生的方式进程间通信和同步Linux下的线程进程间通信概述现在linux使用的进程间通信方式:()无名管道(pipe)和有名管道(FIFO)()消息队列()共享内存()信号量()信号(signal)()套接字(socket)进程间通信概述进程间通信有如下一些目的:数据传输:一个进程需要将它的数据发送给另一个进程。共享数据:多个进程想要操作共享数据一个进程对共享数据的修改别的进程应该立刻看到。通知事件:一个进程需要向另一个或一组进程发送消息通知它(它们)发生了某种事件(如进程终止时要通知父进程)。资源共享的同步:多个进程之间共享同样的资源。为了作到这一点需要内核提供锁和同步机制。进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程)此时控制进程希望能够拦截另一个进程的所有陷入和异常并能够及时知道它的状态改变。管道最早的一种进程间通信方式半双工方式只能在有共同祖先的进程之间使用一般是父子进程创建出管道后调用fork产生新进程在父子进程间使用shell命令中的管道:ls|grep“music”管道通信管道通信例如:ps|grepvsftpd管道是单向的、先进先出的、无结构的字节流它把一个进程的输出和另一个进程的输入连接在一起。写进程在管道的尾端写入数据读进程在管道的首端读出数据。数据读出后将从管道中移走其它读进程都不能再读到这些数据。管道提供了简单的流控制机制。进程试图读空管道时在有数据写入管道前进程将一直阻塞。同样管道已经满时进程再试图写管道在其它进程从管道中移走数据之前写进程将一直阻塞。管道主要用于不同进程间通信。管道通信管道有一些固有的局限性:因为读数据的同时也将数据从管道移去因此管道不能用来对多个接收者广播数据。管道中的数据被当作字节流因此无法识别信息的边界。如果一个管道有多个读进程那么写进程不能发送数据到指定的读进程。同样如果有多个写进程那么没有办法判断是它们中那一个发送的数据。半双工管道#include<unistdh>intpipe(intfd)功能:创建一个简单的管道若成功则为数组fd分配两个文件描述符其中fd用于读取管道fd用于写入管道。返回值:成功返回失败返回。pipe调用成功后的状况半双工管道fdfd管道内核单个进程中的管道fdfd管道父子进程共享的管道fdfd内核父进程子进程fd管道fd内核父进程子进程父子进程共享的管道*simplepipec*parentreadcharsfromstdin,thensendthemtochildthroughpipe,*childreceivecharsfrompipe,thendisplayonstdout*#include<stdioh>#include<unistdh>#defineBUFSIZEintmain(void){intpid,fd,ncharbufBUFSIZEif(pipe(fd)<)errsys("pipeerror")if((pid=fork())<)errsys("forkfailure")elseif(pid==){childclose(fd)while((n=read(fd,buf,BUFSIZE))>){write(STDOUTFILENO,"receivefromparent:",)write(STDOUTFILENO,buf,n)}if(n<)errsys("readerror")close(fd)printf("exitchildn")exit()}close(fd)while((n=read(STDINFILENO,buf,BUFSIZE))>)write(fd,buf,n)if(n<)errsys("readerror")close(fd)printf("exitparentn")}半双工管道如果一个管道的写端口关闭了读操作返回可以复制写描述符让多个进程向同一个管道里面写如果一个管道的读端口关闭了写操作返回errno设置为EPIPE产生SIGPIPE信号多个进程写一个管道如果我们写的数据小于PIPEBUF数据相互之间不会交叉否则就可能交叉利用管道同步进程演示pipesyn命名管道(FIFO)命名管道和一般的无名管道基本相同但也有一些显著的不同:命名管道是在文件系统中作为一个特殊的文件而存在的。不同祖先的进程之间可以通过命名管道共享数据。当共享管道的进程执行完所有的IO操作以后命名管道将继续保存在文件系统中以便以后使用。无名管道只能由相关进程使用它们共同的祖先进程创建了管道。但是通过FIFO不相关的进程也能交换数据。创建命名管道#include<systypesh>#include<sysstath>intmkfifo(constchar*pathname,modetmode)功能:创建命名管道返回:若成功则为若出错则为建立管道后就可以像普通文件一样读写操作若不指定ONONBLOCK只读方式打开时会阻塞直到有进程以写方式打开同样写方式打开时会阻塞直到有进程以读方式打开命名管道(FIFO)在shell的两个管道之间传送数据mkfifofifoprog<fifoprog<infile|teefifo|prog客户端和服务器间互相传数据IPC结构消息队列、信号量和共享内存有很多共同之处每一种结构都有一个内部的非负整数标识从小到大分配外部使用keyt类型标识符每创建一个结构体就指定一个keyt类型标识符服务器使用IPCPRIVATE分配一个结构体把返回的标识符存在一个地方让客户端来了读取或是父子进程服务器和客户端约定一个公共的标识服务器和客户端约定一个路径(已存在的文件)和()的数来生成一个标识keytftok(constchar*path,intid)IPC结构使用get方得到一个IPC结构体如果key是IPCPRIVATE就创建一个新结构体如果key没有与已存在的结构体关连并且指定IPCCREAT标志也会创建一个新的结构体要得到已有的结构体就不能指定IPCCREAT或IPCPRIVATE标志如果要创建一个新的结构体同时指定IPCCREAT和IPCEXCL标志能防止引用一个已有的结构体如果结构体已存在就返回错误EEXISTIPC结构每个结构体都关连一个权限和用户结构体IPC结构每个结构体都是系统全局的但是没有引用计数不会被自动移除容易因为编程不严格造成内存泄露无法通过lschmod等命令访问到增加命令ipcs和ipcrm不是文件描述符无法使用高级IO消息队列概述消息队列是存在内核当中带ID的消息链表用户可以从消息队列中添加消息、读取消息。具有一定的FIFO特性但可以实现消息的随机查询这些消息存在于内核中由“队列ID”来标识消息队列的实现消息队列的实现包括创建和打开消息队列、添加消息、读取消息和控制消息队列创建或打开消息队列:msgget。这里创建的消息队列的数量会受到消息队列数量的限制添加消息:msgsnd函数它把消息添加到已打开的消息队列末尾读取消息:msgrcv它把消息从消息队列中取走与FIFO不同的是这里可以指定取走某一条消息控制消息队列:msgctlintmsgget(keyt,intflag)返回消息队列的id错误返回msgget函数用于创建新的消息队列或打开已有队列消息队列每个消息队列都有一个msgiddes结构表示当前状态消息队列intmsgsnd(intmsqid,constvoid*ptr,sizetnbytes,intflag)把一个新的消息添加到消息队列尾部正确返回错误返回每个消息有一个长整型表示类型一个非负的长度和实际的数据长度标志位可以指定IPCNOWAIT指定非阻塞后如果消息队已满msgsnd立即返回错误EAGAIN若未指定阻塞标志msgsnd将会一直阻塞直到有空间放消息为止如果在阻塞过程中消息队列被移除返回错误EIDRM如果在阻塞过程中被信号打断返回错误EINTRptr指向mymesg结构体消息队列intmsgrcv(intmsqid,void*ptr,sizetnbytes,longtype,intflag)从消息队列上取消息返回消息中的数据部分大小ptr指向mymesg结构类型nbytes指定缓冲区大小如果返回值比nbytes大并且flag设置了MSGNOERROR消息就会被截取否则返回错误EBIGtype用于指定按类型取=取队列上第一个消息>取队列上类型等于type的第一个消息<取队列上类型小于等于type绝对值的第一个消息消息队列intmsgctl(intmsqid,intcmd,structmsqiddes*buf)正确返回错误返回命令选项IPCSTAT取得当前状态IPCSET设置msgpermuid,msgpermgid,msgpermmode,andmsgqbytes能被有效用户ID是msgpermcuid或msgpermuid或超级用户进程修改。长度只能被超级用户修改IPCRMID移除消息队列和所有消息只能被有效用户ID是msgpermcuid或msgpermuid或超级用户进程执行信号量信号量是由荷兰科学家Dijkstra提出的是一种卓有成效的进程同步机制。原理与进程同步一节讲的相同,但较复杂不是一个单独的值,需要定义一个信号量集合创建信号量与初始化是独立的过程,无法原子完成不会自动移除,可能造成内存泄露每个信号量在内核中都有一个semidds结构信号量intsemget(keytkey,intnsems,intflag)功能:创建一个新的信号量或取得一个新的信号量返回值:成功返回信号量标志码失败返回。参数:key整型值其它进程访问信号量的依据。nsems信号量个数一般为。semflg标志类似open()的标志相当于文件的访问权限信号量intsemop(intsemid,structsembufsemoparray,sizetnops)正确返回,错误返回用于在信号量集合上执行一组操作,改变信号量的值参数:semid信号量标志码。sops结构体指针包含了具体操作。nsops结构体数量等于。信号量structsembuf{unsignedshortsemnumshortsemopshortsemflg}这三个字段的意义分别为:semnum:操作信号在信号集中的编号第一个信号的编号是。semop:如果其值为正数该值会加到现有的信号内值中。通常用于释放所控资源的使用权如果semop的值为负数而其绝对值又大于信号的现值操作将会阻塞直到信号值大于或等于semop的绝对值。通常用于获取资源的使用权如果semop的值为则操作将暂时阻塞直到信号的值变为。semflg:信号操作标志可能的选择有两种IPCNOWAIT对信号的操作不能满足时semop()不会阻塞并立即返回同时设定错误信息。IPCUNDO程序结束时(不论正常或不正常)保证信号值会被重设为semop()调用前的值。这样做的目的在于避免程序在异常情况下结束时未将锁定的资源解锁造成该资源永远锁定。信号量intsemctl(intsemid,intsemnum,intcmd……*unionsemunarg*)功能:控制信号量信息。返回值:成功返回否则。参数:semid信号量标志码。semnum信号量编号。cmd要进行的操作。第四个参数是unionsemun的实例具体值依赖cmd。信号量命令个数比较多IPCSTAT取得信号量集合的semidds结构,存在argbug指向的区域IPCSET设置sempermuid,sempermgid,andsempermmodeIPCRMID从系统移除信号量集合GETALL取得所有信号量值,存在argarray指向区域SETALL设置所有信号量值,从argarray指向区域读取具有依赖关系的作业调度问题设P、P、P、P、P、P为一组合作进程其前驱图如下右图所示。七个同步信号量a、b、c、d、e、f、g分别表示进程之间的前驱关系如图所示其初值均为。这六个进程的同步描述如下:PPPPPPabcdfeg解法()P(){执行P的代码v(a)v(b)}PPPPPPabcdfeg解法()P(){p(a)执行P的代码v(c)v(d)}PPPPPPabcdfeg生产者消费者问题生产者消费者问题是最著名的进程同步问题。它描述了一组生产者进程向一组消费者进程提供产品它们共享一个有界缓冲池。缓冲池中的每个缓冲区可以存放一个产品生产者进程不断生产产品并将产品放入缓冲池中消费者进程不断从缓冲池内取出产品并消费。生产者消费者问题示意图同步关系有:当缓冲池满时生产者进程需等待当缓冲池空时消费者进程需等待。诸进程应互斥使用缓冲池。共享内存概述一种最为高效的进程间通信的方式进程可以直接读写内存。不需要任何数据的拷贝内核专门留出一段内存区使得多个进程间交换信息此段内存区可以由需要访问的进程将其映射到自己的私有地址空间共享内存的实现实现分为两个步骤创建共享内存:用到的函数shmget即从内存中获得一段共享内存区域映射共享内存:把这段创建的共享内存映射到具体的进程空间使用的函数shmat还有撤销映射的操作函数为shmdt*共享内存多个进程共享一块内存区域速度快,不需要复制内存多个进程访问公共数据需要使用信号量来同步内核为每个共享内存段维护一个结构共享内存共享内存原理示意图函数格式Shmget函数语法要点所需头文件#include<systypesh>#include<sysipch>#include<sysshmh>函数原型Intshmget(keytkey,intsize,intshmflg)函数传入值Key:IPCPRIVATEsize:共享内存区大小Shmflg:同open函数的权限位也可以用八进制表示法返回值成功:共享内存段标识符出错:*共享内存void*shmat(intshmid,constvoid*addr,intflag)把共享内存加载到进程空间返回值:成功返回共享内存的虚拟地址起始地址失败返回。如果addr是空,加载到第一个可用的地址addr非空,并且没有指定SHMRND标志,加载到addr处addr非空,并且指定SHMRND标志,加载到地址(addr(addrmodulusSHMLBA))处共享内存#include<sysshmh>intshmdt(constvoid*shmaddr)功能:断连共享内存区的映射,把内存与进程分离,但不从系统内移除返回值:成功时返回。失败时返回。参数:shmaddr是共享内存的虚拟地址起始地址。shmatc共享内存#include<sysshmh>intshmctl(intshmid,intcmd,structshmidds*buf)功能:共享内存控制函数。返回值:成功返回失败返回。参数:shmid共享内存的ID。cmd允许的操作最常用的包括:IPCRMID删除共享内存段。buf保存内存模式状态和访问权限的数据结构通常为。信号通信信号概述信号是UNIX中使用的进程通信最古老的一种方法。在软件层次上对中断机制的一种模拟是一种异步通信方式信号可以直接进行用户空间进程和内核进程之间的交互内核进程也可以利用它来通知用户空间进程发生了哪些系统事件一个完整的信号生命周期可以分为个重要阶段这个阶段由个重要事件来刻画信号产生信号在进程中注册信号在进程中注销执行信号处理函数*信号概述产生信号:当用户按某些终端键时可以产生信号。例如:在终端上按CtrlC键通常产生中断信号(SIGINT)。这是停止一个已失去控制程序的方法。硬件异常产生信号:除数为、无效的存储访问等等。这些条件通常由硬件检测到并将其通知内核。然后内核为该条件发生时正在运行的进程产生适当的信号。例如对执行一个无效存储访问的进程产生一个SIGSEGV。相邻两个事件的时间间隔构成信号生命周期的一个阶段信号处理有多种方式一般是由内核完成的当然也可以有用户进程完成不可靠信号的处理过程发现该信号已经在进程中注册则忽略该信号故若前一个信号还未注销又产生了相同的信号就会产生信号丢失可靠信号的处理过程发现信号不管该信号是否已经在进程中注册都会被再注册所有可靠信号都支持排队而不可靠信号则都不支持排队*信号可以要求系统在某个信号出现时按照下列三种方式中的一种进行操作。()忽略此信号。大多数信号都可使用这种方式进行处理但有两种信号却决不能被忽略。它们是:SIGKILL和SIGSTOP。这两种信号不能被忽略的原因是:它们向超级用户提供一种使进程终止或停止的可靠方法。另外如果忽略某些由硬件异常产生的信号(例如非法存储访问)则进程的行为是未定义的。()捕捉信号。为了做到这一点要通知内核在某种信号发生时调用一用户函数。在用户函数中可执行用户希望对这种事件进行的处理。如果捕捉到SIGCHLD信号则表示子进程已经终止所以此信号的捕捉函数可以调用waitpid以取得该子进程的进程ID以及它的终止状态。()执行系统默认动作。对大多数信号的系统默认动作是终止该进程。下面是几个常见的信号。)SIGHUP:从终端上发出的结束信号)SIGINT:来自键盘的中断信号(CtrlC))SIGQUIT:来自键盘的退出信号(Ctrl))SIGFPE:浮点异常信号(例如浮点运算溢出))SIGKILL:该信号结束接收信号的进程)SIGSEGV:对执行一个无效存储访问的进程产生一个SIGSEGV)SIGALRM:进程的定时器到期时发送该信号)SIGTERM:kill命令发出的信号)SIGCHLD:标识子进程停止或结束的信号)SIGSTOP:来自键盘(CtrlZ)或调试程序的停止执行信号…………信号发送与捕捉kill()和raise()kill函数同kill系统命令一样可以发送信号给进程或进程组。注意:它不仅可以中止进程也可以向进程发送其他信号raise()与kill不同的是它允许进程向自身发送信号alarm()和pause()alarm也称为闹钟函数它可以在进程中设置一个定时器当定时器指定的时间到时它就向进程发送SIGALARM信号。注意:一个进程只能有一个闹钟时间如果在调用alarm之前已设置过闹钟时间则任何以前的闹钟时间都被新值所代替pause()函数是用于将调用进程挂起直至扑捉到信号为止。可用于判断信号是否已到信号的处理特定的信号是与一定的进程相联系的一个进程可以决定在该进程中需要对哪些信号进程什么样的处理*信号处理函数#include<signalh>intkill(pidtpid,intsig)功能:发送信号到进程。返回值:成功返回否则返回。#include<unistdh>intalarm(unsignedintseconds)功能:在secends秒后发送SIGALARM信号。若secends为则取消已设置闹铃。返回值:成功返回上一个闹铃还剩余多长时间失败返回。同时一个进程还可以选择如何处理信号建立信号与进程之间的对应关系信号处理简单的signal函数使用信号集函数组signal()只需把要处理的信号和处理函数列出即可主要用于前种非实时信号的处理不支持信号传递信息信号集函数组涉及一系列的函数这些函数按照调用的先后次序分为以下几大功能模块创建信号集合:创建用户感兴趣的信号登记信号处理器:主要用于决定进程如何处理信号检测信号:信号处理的后续步骤*信号处理函数#include<signalh>sighandlertsignal(intsig,sighandlerthandler)功能:信号处理函数。返回值:成功返回可用信号处理函数失败返回SIGERR。参数:sig要捕获的信号。handler信号处理函数。还可以是以下取值:SIGIGN屏蔽该信号SIGDFL恢复默认行为注:该函数简单但可靠性低可由sigaction()代替。signalc培训大纲程序、进程和线程的概念进程产生的方式进程间通信和同步Linux下的线程线程概述进程是系统中程序执行和资源分配的单位。每个进程都拥有自己的数据段、代码段和堆栈段故进程在进行切换等操作时需要进行大量上下文的切换工作为进一步减少处理器的空转时间支持多处理器和减少上下文切换开销进程演化出另一个概念线程进程内的基本调度单位也可称为轻量级进程线程是在共享内存空间中并发的多道执行路径共享一个进程的资源如文件描述和信号处理大大减少上下文切换的开销一个进程可以有多个线程既有多个线程控制表及堆栈寄存器但却共享一个用户地址空间*线程基本操作线程的创建和退出函数说明:创建线程实际上就是确定调用该线程函数的入口点通常使用pthreadcreate线程创建之后开始运行相关的线程函数该函数运行完之后线程也就退出。另一种退出线程的方法是使用函数pthreadexit,这是线程的主动行为在使用线程函数时不能随意使用exit退出函数进行出错处理。由于exit的作用是使调用进程终止往往一个进程包含多个线程故在使用exit之后该进程中的所有线程都终止由于一个进程中的多个线程是共享数据段因此通常在线程退出后退出线程所占用的资源并不会随着线程的终止而得到释放。在线程中使用pthreadjoin函数用于将当前线程挂起等待线程的结束。此函数是一个线程阻塞函数调用它的函数将一直等待到被等待的线程结束为止。函数返回被等待线程的资源就收回*函数格式所需头文件#include<pthreadh>函数原型Intpthreadcreate((pthreadt*thread,pthreadattrt*attr,void*(*startroutine)(void*),void*arg))函数传入值Thread:线程标识符Attr:线程属性设置Startroutine:线程函数的起始地址Arg:传递给startroutine的参数函数返回值成功:出错:所需头文件#include<pthreadh>函数原型Voidpthreadexit(void*retval)函数传入值Retval:pthreadexit调用者线程的返回值可有其他函数如pthreadjoin来检索获取*函数格式所需头文件#include<pthreadh>函数原型Intpthreadjoin((pthreadtth,void**threadreturn))函数传入值Th:等待线程的标识符Threadreturn:用户定义的指针用来存储被等待线程的返回值(不为时)函数返回值成功:出错:*线程访问控制由于线程共享进程的资源和地址空间因此对这些资源进行操作时必须要考虑到线程间资源访问的惟一性问题。Mutex互斥锁线程控制函数说明:一种简单的加锁的方法来控制对共享资源的存取。这个互斥锁只有两种状态即上锁和解锁可以把互斥锁看作全局变量。在同一时刻只能有一个线程掌握某个互斥上的锁拥有上锁状态的线程能够对共享资源进行操作。若其他线程希望上锁一个已经上锁了的互斥锁则该线程就会挂起直到上锁的线程释放掉互斥锁为止。互斥锁的操作主要包括以下几个步骤:初始化:pthreadmuteinit上锁:pthreadmutelock判断上锁:pthreadmutetrylock解锁:pthreadmuteunlock消除互斥锁:pthreadmutedestroy**simplepipec*parentreadcharsfromstdin,thensendthemtochildthroughpipe,*childreceivecharsfrompipe,thendisplayonstdout*#include<stdioh>#include<unistdh>#defineBUFSIZEintmain(void){intpid,fd,ncharbufBUFSIZEif(pipe(fd)<)errsys("pipeerror")if((pid=fork())<)errsys("forkfailure")elseif(pid==){childclose(fd)while((n=read(fd,buf,BUFSIZE))>){write(STDOUTFILENO,"receivefromparent:",)write(STDOUTFILENO,buf,n)}if(n<)errsys("readerror")close(fd)printf("exitchildn")exit()}close(fd)while((n=read(STDINFILENO,buf,BUFSIZE))>)write(fd,buf,n)if(n<)errsys("readerror")close(fd)printf("exitparentn")}**shmatc****signalc*****

VIP尊享8折文档

用户评价(0)

关闭

新课改视野下建构高中语文教学实验成果报告(32KB)

抱歉,积分不足下载失败,请稍后再试!

提示

试读已结束,如需要继续阅读或者下载,敬请购买!

文档小程序码

使用微信“扫一扫”扫码寻找文档

1

打开微信

2

扫描小程序码

3

发布寻找信息

4

等待寻找结果

我知道了
评分:

/71

C语言-进程间通信

¥25.0

会员价¥20.0

VIP

在线
客服

免费
邮箱

爱问共享资料服务号

扫描关注领取更多福利