我要投搞

标签云

收藏小站

爱尚经典语录、名言、句子、散文、日志、唯美图片

当前位置:港彩神鹰 > 读入原语 >

POSIX API

归档日期:06-27       文本归类:读入原语      文章编辑:爱尚语录

  POSIX,全称为可移植性操作系统接口,是一种关于信息技术的IEEE标准。它包括了系统应用程序接口(API),以及实时扩展(C语言)。

  该标准的目的是定义了标准的基于UNIX操作系统的系统接口和环境来支持源代码级的可移植性。现在,标准主要提供了依赖C语言的一系列标准服务,再将来的版本中,标准将致力于提供基于不同语言的规范。

  该标准对核心需求部分定义了一系列任何编程语言都通用的服务,这一部分服务主要从其功能需求方面阐述,而非定义依赖于编程语言的接口。语言规范主要有两部分组成。一部分包括了访问核心服务的编程语言的标准接口,这些核心服务为标准中基于编程语言的核心需求部分所定义;另一部分包含了一个特殊语言服务的标准接口。基于任何语言,与该标准一致的执行都必须遵循语言规范的任何章节。

  (2)定义足够的实现规范和性能相关的函数,以便允许实时应用程序完成系统的确定性的响应;

  系统须支持标准中定义的接口,系统能够提供标准中没有要求到的函数和工具。在遵循于该标准的实现中,一种一致性文档是需要用到的,它必须具有与该标准相同的结构,包含有全名,数字,和标准所指示的日期,以及头文件limits.h和unistd.h中的界限值等等。该一致性文档详细说明了标准中定义的执行行为。该标准要求了应用程序的一致性,所有遵循标准的应用程序都使用基于C语言的服务。

  该标准中定义了一系列术语,如一致性文档,被定义的实现,可能性,无用的特性等,还定义了一些通用名词,如绝对路径,存取模式,地址空间,适当权限,定时器,异步I/O操作,后台进程,后台进程组,块文件,阻塞进程等等。

  这些数据类型在头文件sys/types.h中定义,它包含了至少以下类型:

  当一个进程开始执行时,将调用一个表示环境的字符串数组,这个数组为外部变量environ所指向,其定义如下:

  在该章中,标准还总体介绍了c语言定义的一些标志符,数字方面的限制,以及一些符号常量,这些在以后的章节中都会一一出现。

  调用时需要引用的头文件是unistd.h,fork()创建了一个新的进程。子进程中返回0,父进程中返回子进程ID,出错返回-1。

  exec系列的函数用一个新的进程映像替代了当前的进程的正文、数据、堆和栈段,这个新的进程映像创建于一个规则的可执行文件,叫做新进程映像文件。执行成功无返回值因为调用进程映像以为新的进程映像所覆盖。

  (1)从main()函数返回时或者执行exit()或_exit()函数时正常的终止;

  wait()和waitpid()允许调用进程获得它的一个子进程的状态信息。wait()函数将挂起调用进程直到获得了它的子进程的状态信息,或者是直到获得一个终止进程信号;如果pid=-1并且options=0,waitpid()函数功能将和waitpid()相同,否则它的功能将依据pid和options的值而改变。

  区别:在一个子进程终止前,wait()使其调用者阻塞,而waitpid()有一个选项,可使调用者不阻塞。waitpid()并不等待在起调用之后的第一个终止子进程,它有若干个选项,可以控制它所等待的进程。

  在头文件signal.h中声明了sigset_t类型和sigaction结构。完成所定义的信号分三类:必需的信号、任务控制信号、内存保护信号。分别如下表:

  每一个进程有一个进程标记(process mask),它定义了一组产生但被阻塞传递的信号集。sigaction(),sigpromask(),sigsuspend()函数控制这个进程标记的行为。

  该函数发送一个信号到一个由pid指明的进程或者进程组,sig标志了信号类型,其值是0或者上表中的值。如果发送成功,返回0,否则返回1。

  sigemptyset()初始化由set指向的信号集,清除其中所有信号;

  所有应用程序在使用信号集前,要对该信号集调用sigemptyset()和sigfillset()一次;

  该函数允许调用函数检查与确定的信号相联系的行为,参数sig确定了信号,sigaction结构在头文件signal.h中被定义,描述了所采取的行为。如果参数act不为null,它指向一个结构,它指定了与信号相联系的行为。如果参数oact不为null,先前与信号相联系的行为将被存储到由oact指向的地方。

  该函数sigprocmask可以检测或更改其信号屏蔽字。首先,若oset是非空指针,那么进程的当前信号屏蔽字通过oset返回。其次,若set是一个非空指针,则参数how指示如何修改当前信号屏蔽字。如果set是空指针,则不改变该进程的信号屏蔽字,how的值也无意义。

  该函数返回一个信号集,其中的各个信号对于调用进程是阻塞的而不能递送,因而也一定是当前未决的。该信号集通过set参数返回。

  将进程的信号屏蔽字设置为sigmask所指向的值。在捕捉到一个信号或发生了一个会中止该进程的信号之前,该进程被挂起。如果捕捉到了一个信号好而且从该信号处理程序返回,则sigsuspend()返回,并且该进行的信号屏蔽字设置为调用sigsuspend()之前的值。

  注意,该函数没有成功返回值。如果它返回到调用者,则总是返回-1,并将errno设置为EINTR(表示一个被中断的系统调用)。

  Sigsuspend()的另一种应用时等待一个信号处理程序设置一个全局变量。

  该函数从参数set所确定的信号集中选择一个未定的信号出来。如果该函数成功,返回一个信号数;否则返回-1。

  该函数功能是使由signo确定的信号将参数value所确定的值发送到由pid指明的进程中去。

  使用该函数可以设置一个计时器,在将来某个指定的时间该计时器会超时。当计时器超时时,产生SIGALRM信号。如果不忽略或者不捕捉该信号,则其默认动作时终止调用该函数的进程。

  该函数挂起一个调用进程直至捕捉到一个信号,这个信号或者执行信号跟踪功能或者是终止该进程。如果是终止进程,该函数不返回;如果是执行信号跟踪功能,则该函数在信号跟踪函数返回后也要返回。

  该函数使当前进程从执行状态转化为挂起状态,直到参数seconds所指定的一段实时时间过去后,或者是一个唤醒信号跟踪功能或终止进程功能的信号到来。该挂起时间由于系统的其他调度活动可能会比要求的时间长。

  getuid()返回调用进程的真实用户ID, geteuid()返回调用进程的有效用户ID,getgid()返回调用进程的真实组ID,getegid()返回调用进程的有效组的ID。

  这两个函数分别根据进程的权限设置真实用户ID,有效用户ID,真实组ID,有效组ID。

  该函数在队列的组列表中填入调用进程的辅助组ID。参数gidsetsize确定了组列表中的元素个数。

  如果调用进程不是进程组的组长,则该函数将创建一个新会话。结果将发生下面三件事:1、该进程成为一个新进程组的组长进程。此时,该新进程是新会线、该进程成为一个新进程组的组长进程。新进程组ID是该调用进程的进程ID。3、该进程没有控制终端。如果再调用setsid()之前该进程有一个控制终端,那么这种联系也会被中断。

  如{_POSIX_JOB_CONTROL}被定义,则该函数用来加入已经存在的进程组或者创建一个新的进程组。

  该函数返回与当前主机与操作系统有关的信息。通过该函数的参数向其传递一个utsname结构的地址,然后改函数填写此结构。

  该函数返回自从公元1970年1月1日00:00:00以来的某个时间值,以秒为单位。参数calptr指向一个时间值所存储的地方。

  该函数在环境列表查找字符串name=value,返回指向value的指针。如果没有找到,则返回null。

  putenv()取形式为name=value的字符串,将其放到环境表中。如果name已经存在,则先删除其原来的定义。

  setenv()将name设置为value。如果再环境中name已经存在,那么若rewrite非0,则首先删除其现有的定义,若rewrite为0,则先不删除现有定义。

  该函数产生一个字符串,作为路径名,提交到当前进程的当前控制终端, 用来确定控制终端的名字。此函数的主要作用是帮助提高向其他操作系统的可移植性。

  ttyname()返回一个指针指向一个字符串,它包含了该文件描述符上打开的终端设备的路径名;

  该函数提供了一个应用方法来决定可配置系统变量的当前值。参数name代表了所查询的系统变量。

  头文件dirent.h定义了一个结构和目录程序用到的类型,没有确定的文件内部格式。readdir()返回了一个指针指向一个类型对象struct dirent。

  opendir()根据参数dirname打开一个目录流;readdir()返回一个指针,它指向一个目录流中当前位置的目录入口,目录流由参数dirp指向;rewinddir()重置目录流的位置到目录的起点;closedir()关闭目录流,如成功,则返回“0”值。

  open()在文件和文件描述符之间建立了一个连接,它创建了一个指向一个文件的打开文件描述,参数path指向文件的路径名。

  umask()设置进程的文件模式创建标记到cmask,并且返回原来的标记值。

  参数existingpath指向路径名来命名存在文件,参数newpath指向一个路径名,它命名了一个创建的新的目录入口。该函数为已存在的文件自动的创建一个新的连接,并且将文件连接数加1。如果newpath已经存在,则返回出错。

  该函数创建了一个指向path1的新目录项path2,在创建此符号链接时,不需要求path1已经存在。

  打开符号链接,此函数组合了open,read,close的所有操作。如果此函数成功执行,则返回读入buf的字节数。

  该函数依据参数path创建一个新的目录。新目录的允许位根据mode初始化。

  mkfifo()创建一个新的fifo类型文件,它由pathname指向的路径名命名。

  FIFO有下面两种用途:1、FIFO由shell命令使用以便将数据从一条管道线传到另一条,为此无需创建中间临时文件。2、FIFO用于客户进程-服务器进程应用程序中,以在客户进程和服务器进程之间传递数据。

  该函数删除目录项,并将有pathname所引用文件的链接计数减1。如果还有指向该文件的其他链接,则仍可以通过其他链接访问该文件的数据。如果出错,则不对该文件做任何更改。

  该函数改变一个文件的名字,参数old指向被重命名文件的路径名,参数new指向文件的新路径名。

  fstat()函数获得一个已经打开的文件的信息,并存入缓冲区buf内;lstat()函数获得一个符号链接的文件的信息,并保存在buf缓冲区内。

  chmod()和fchmod()函数改变路径下的文件权限变量mode,若修改正确,返回0,否则返回-1。不同的是chmod()是在制定的文件上进行操作,而fchmod()则对已打开的文件进行操作。

  除了所引用的文件时符号链接外,这三个函数的操作相似。在符号链接的情况下,lchown()更改符号链接本身的所有者,而不是该符号链接所指向的文件。

  这两个函数将把现有的文件长度阶段为length字节。如果该文件以前的长度大于length,则超过length以外的数据就不再能访问了。函数ftruncate()是POSIX.1的组成部分,truncate()函数式POSIX.1功能的XSI扩展部分。

  这两个函数为fcntl()服务提供了两个选择的接口,用到了F_DUPFD命令。

  关闭一个文件。关闭一个文件时还会释放该进程加载该文件上的所有记录锁。当一个进程终止时,内核自动关闭它所有打开的文件。

  从打开文件中读数据。如read成功,则返回读到的字节数。如果已到达文件结尾,则返回0。

  fcntl()为打开的文件提供了一系列控制,参数fildes是一个文件描述符。cmd决定了控制的内容。

  若whence是SEEK_SET,则将该文件的偏移量设置为距文件开始处offset个字节。

  若whence是SEEK_CUR,则将该文件的偏移量设置为其当前值加offset,offset可为正或负。

  若whence是SEEK_END,则将该文件的偏移量设置为文件长度加offset,offset可为正或负。

  该函数用来暗示所有的文件描述数据被传输到了存储设备上。该函数值对由文件描述符filedes指定的单一文件起作用,并且带写磁盘操作结束,然后返回。

  该函数迫使当前所有排队的I/O操作进入同步 I/O状态。该函数类似于函数fsync(),但它只影响文件的数据部分。

  参数fildes是文件描述符,参数aiocbp指向异步I/O控制块上的请求删除部分。

  标准定义该函数挂起调用进程直到至少一个list指向的异步I/O操作完成,或者一个信号中断了一个函数,或者超时了(timeout指定)。

  该函数迫使所有与(参数aiocbp指向的)结构aiocb中aio_fildes所指定的文件相关异步I/O操作进入同步状态。

  ●进程组一个终端可以具有与它相关的前台进程组,它发挥特定的角色,后面会讲到。

  该结构在termios.h中定义,在控制特定的终端I/O特性中要用到。

  如果终端使用异步连续数据传输,tcsendbreak()引起在一段时间内连续的0位传输;tcdrain()等待直到输出传输完毕;tcflush()函数刷清输入缓冲区或输出缓冲区;tcflow()用于对输入和输出流控制进行控制。

  这两个函数都有一个指向termios结构的指针作为其参数,它们返回当前终端的属性,或者设置该终端的属性。

  每个标准I/O流都有一个与其相关联的文件描述符,可以对一个流调用fileno函数以获得其描述符。该函数是POSIX.1支持的扩展。

  该函数获取一个现有的文件描述符(我们可能从open,dup,dup2,fcntl,pipe,socket,socketpair或accept函数得到此文件描述符),并使一个标准的I/O流与该描述符相结合。该函数常用于由创建管道和网络通信通道函数返回的描述符。

  一个单一的文件描述说明可以通过流和文件描述符访问,流或者是文件描述符被称作位打开文件的句柄,一个打开文件说明可以有多个句柄。句柄可以在不影响重要的打开文件说明的情况下被创建和删除,创建如fcntl(),dup(),fdopen(),fileno(),fork();删除如fclose(),close()。

  b)fclose():该函数完成在与FILE流相关的,对文件描述符的close()功能。

  d)fflush():如果流可写或者缓存数据还没有写入文件时,该函数标记下基础文件st_ctime和st_mtime的值。

  用户数据库包含的信息有:用户名,用户的数字ID,组的数字ID,初始化的工作目录和初始化的用户程序。

  (2) 若此信号量的值为正,则进程可以使用该资源。进程可以使用该资源。进程将信号量只减1,表示它使用了一个资源单位。

  (3) 若此信号量的值为0,则进程进入休眠状态,直至信号量值大于0.进程被唤醒后,它返回至第(1)步。

  该函数被用来初始化sem引用的未命名信号量。在成功调用该函数以后,在接下来的sem_wait(),sem_trywait(),sem_post(),sem_destroy()的调用中,该信号量将被用到。如果参数pshared不为零,信号量将在进程中被共享,任何可以访问信号量sem的进程都可以使用sem。只有sem能被用来进行同步。如果参数pshared为零,则结构不确定。如果标准中未定义,可以由执行者来支持该函数。

  该函数用来删除sem引用的未命名信号量,只有在sem_init()中创建的信号量才能被该函数删除。

  该函数在进程和命名信号量之间创建一个链接。接着调用带有信号量名name的该函数,进程引用与name相关的信号量。该信号量在一些函数的调用中用到,如sem_wait(),sem_trywait(),sem_post,和sem_close()。信号量一直可用知道调用函数sem_close(),_exit,exec()关闭它。参数oflag控制是否信号量由sem_open()创建或者仅被它访问。

  该函数用来提示调用进程已经完成使用sem所指明的信号量。该函数释放系统资源,这些资源被拥有该信号量的进程占有。

  该函数将移走被字符串name命名的信号量。如果该信号量当前被其他进程引用,则该函数对信号量状态没有影响。如果一个和更多的进程打开了该信号量,则销毁该信号量被延迟知道所有的信号量被sem_close(),_exit(),exec关闭。

  sem_wait()锁定sem引用的一个信号量,对该信号进行锁定操作。如果信号量为0,调用进程将不会返回直到锁定了这个信号量或者被一个信号中断。Sem_trywait()只能在信号量当前没被锁定的情况下锁定它,否则将不会锁定信号量。成功返回,信号量的状态将被锁定直到sem_post()被调用并且成功返回。

  该函数通过对一个信号量的解锁操作解锁一个被sem引用的信号量。如果该操作的结果,信号量值为正数,则没有进程被锁定来等待一个信号量解锁,信号量值是单一的增加。如果信号量值为0,则进程被锁定来等待一个信号量被允许从sem_wait()成功返回。

  该函数更新参数sval所引用的位置,在不改变信号量状态的情况下得到信号量值。更新的值代表了一个确切的值,它产生在调用中的一个不定时刻,但它返回给调用进程是不一定需要信号量的确定值。如果sem被锁定,则sem_getvalue()返回的值为0,或者负数,它代表了等待信号量的进程数。

  内存锁定和内存映象文件以页的方式定义。执行者可以据据页大小的规范限制和排列锁定和映象范围。页的大小,以字节为单位,是一个可配置系统变量。默认为1B。

  mlockall()使进程地址空间所映射的所有页面成为内存驻留区,直到解锁或者进程退出或者execs另一个进程映象。参数flags决定了是否被锁定的页面是由当前,(将来,或者两者都是)的进程地址空间映射的。Munlockall()解锁当前所有的进程地址空间映射页面。所有映射到进程地址空间的页面,调用了该函数,将不会被锁定,除非有中断调用mlockall()确定MCL_CURRENT,或者并发调用mlockall()确定MCL_CURRENT。

  mlock()使一个范围的进程地址空间成为内存驻留区(addr决定了空间的起始地址,len决定了空间长度)直到解锁或者进程退出或者execs另一个进程映象;munlock()解锁一个范围的进程地址空间(addr决定了空间的起始地址,len决定了空间长度);

  该函数在一个进程的地址空间和内存对象间创建一个映射,调用格式如:pa=mmap(addr,len,prot,flags,fildes,off);pa代表进程进程地址空间的地址,由执行者定义(addr和flags),len表示空间长度,fildes代表内存对象,off表示偏移量。函数成功调用返回pa,空间地址范开始与pa,长度为连续的len个字节;内存对象开始与off,长度为len字节。参数prot决定了读,写,执行,或一些映射数据的访问活动的集合。

  该函数移去任何包含有进程地址空间的页面的映射关系,该进程地址空间起始于addr,长度为len字节。

  该函数更改访问的保护活动,由参数prot确定。访问对象是一部分进程地址空间,起始于addr,长度为len字节。

  该函数将所有更改了的数据写到拥有存储的地方,它包含了进程地址空间,起始于addr,长度为len字节。如果没有这样的存储区域存在,则给函数没有作用。该函数须保证写操作的完成符合所定义的同步I/O数据的一致完成性。参数flags确定了写的同步/异步性。

  该函数在共享内存对象和文件描述符之间创建了一个连接。它创建了一个打开文件描述涉及到共享内存对象,并且创建了一个文件描述符指向这个打开文件描述。这个文件描述符可悲其他函数用来指向共享内存对象,参数name指向共享内存对象名。如函数调用成功,则返回一个共享内存的文件。文件状态和文件访问模式根据oflag的值来设定。

  该函数移去由name命名的共享内存对象。如果一个或者多个对共内存的引用在对象断开连接的同时退出的话,这个名字应在shim_unlink()返回之前移走,但是对内存对象的移走须延迟到所有对共享内存对打开和映射引用被移去后。

  一个调度参数结构sched_param包括了调度策略所支持的执行者所需要的调度参数,它在头文件sched.h中定义。执行者可根据规对该结构进行扩展。

  该章所阐述的调度术语是从概念模型上定义的,它包含了一组进程列表。这个模型只讨论了可运行进程的处理器调度,但是它注重了在其他资源考虑到处理器调度策略的情况下,增强了实时操作的可预见性。在这里,概念上讲是一个进程列表一个策略。调度策略的目的就是对这一组列表定义允许的操作(例如,在进程列表之中和之间移动进程)。每一个进程应由相关的调度策略和优先级,于每一个策略相关的是一个优先级范围。

  该策略是一种先进先出的调度策略。如果正在执行的进程是被抢占的进程,则他应该在进程列表头;如果一个锁定的进程变成可执行进程,它就进入进程列表尾;当执行进程调用sched_setscheduler(),则函数中确定的进程被改为指定的策略;当执行进程调用sced_setparam(),进程的优先级根据参数param被修改,如果改进程是正在执行和可执行,则它将进入进程列表尾;当正在执行的进程调用seced_yield(),进程进入列表尾。

  该策略与上面的策略不同的是,如果执行中检测到进程的执行时间已经到达或超过了sched_rr_get_interval()所返回的时间片,进程就进入列表尾并且进程列表头移动一个进程进入执行状态。

  pid指明了进程,param指向了sched_param结构,该结构设定了进程的调度参数。如果pid=0,调度参数为调用进程设定。如果pid指定的进程的优先级高于正在指向的进程并且该进程可执行,则抢占现在正在运行的进程。如果当前的策略不是前面将的三种方式,则由执行者定义。

  该函数返回调度参数,如果一个pid进程退出并且调用进程允许,则ID等于pid的进程返回其调用参数。如果pid=0,则返回调用进程的调度参数。

  该函数设置进程的调度策略和调度参数,pid表示进程,policy指明策略,参数param指向的sched_param结构指明了调度参数。执行者可要求请求进程能允许设定自己或其他进程的调度参数。

  该函数返回pid进程的调度策略,其返回值在头文件sched.h中定义。

  时间值结构itimerspec确定了一个初始化的定时器和各进程定时器函数用到的重复间隔。结构包括:

  为了使完成支持实时信号扩展功能,各进程定时器被创建通过排列实时扩展信号来通知定时器超时的进程。Sigevent结构在头文件signal.h中定义,用来创建一个这样的定时器。

  clock_getres()可以得到时钟的确定值,该值由执行者定义而不由进程设定。如果res不为空,则该值被存储在res指向的地方,如果res为空,则时钟决定值不被返回。

  timer_create()创建一个总进程定时器,用来指明时钟,clock_id,作为计时基础。该函数在timerid指向的地方返回一个timer_t类型的定时器ID,该ID在调用进程中必须是唯一的直到定时器被删除。参数evp如果不为空,则指向一个sigevent结构,定义了定时器超时时出现的异步通知。结构中sigev_notify为SIGEV_SIGNAL时,结构就包括了超时时送往进程的信号数和应用数据;如果sigev_notify为SIGEV_NONE,则不发送任何通知;sigev_notify其他的值由完成者自行定义。总进程的定时器不被其子进程通过fork()继承,它应该被exec撤销。

  该函数删除一个指定的定时器,timerid,该定时器是在以前的timer_create()中创建的。

  timer_settime()设置时间直到下一个timerid指定的定时器终止。如果该函数调用时定时器已经被装备,该调用则重置时间直到value确定的下一次终止。如果value的it_value成员为零,定时器被解除。如果flag没有设定为TIMER_ABSTIME,则定时器从调用开始在it_value十亿分之一秒内超时;如果设定为TIMER_ABSTIME,该函数表现为时间直到下一次超时被设定为it_value指定的绝对时间和与timerid相联的时钟值的差值。定时器的再装由value的it_interval成员值来设定。如果参数ovalue不为空,该函数被存储在ovalue引用的地方。该函数要存储时间累计值直到timerid指定的定时器终止或重装定时器值到value参数。在任一时刻,仅有一个单一信号被派了在指定的定时器的进程中。如果支持实时信号扩展,timer_getoverrun()返回定时器终止的溢出值。

  该函数使当前执行的进程挂起直到参数rptp指定的时间间隔到达或者信号被送到调用进程并且其行为就是唤醒信号跟踪功能或者使终止进程。挂起时间也许要比要求时间长是因为参数值向上舍入成一个整数或者是因为系统对其他活动的调度。但是除非被信号打断,挂起时间不会少于tqtp值,这是系统时钟,CLOCK_REALTIME测量的。

  该函数在进程和消息队列之间建立连接。它创建了一个消息队列描述符指向消息队列。参数oflag请求对消息队列发送或接收所需信息。如果调用进程承认对相应保护文件的读写请求,则对接收或发送消息的请求允许被通过。

  该函数撤销消息队列描述符(mqdes)和消息队列之间的关系。如果进程成功的配属了mqdes表示的消息队列通知请求,则这个配属关系被撤销,该消息队列可用于其他进程来配属通知。

  该函数移去路径名name指向的消息队列。如果该调用成功,并且flag没有设为O_CREATE,则mq_open()对于同一个name将会失败。所有对该队列的引用撤销后,该队列才能被关闭。该函数调用不会被阻塞指定所有的引用被关闭。

  该函数添加参数msg_ptr指向的消息到mqdes指定的消息队列中去。参数msg_len表示消息长度,以字节为单位,该参数应小于等于消息队列的mq_msgsize参数,否则调用失败。如果消息队列没有满,则该函数的功能就是插入消息到消息队列的指定位置,这个位置邮msg_prio参数指定。msg_prio大者先插入队列,msg_prio的值应小于等于{MQ_PRIO_MAX}。如果消息已满并且O_NONBLOCK没有设定,该函数阻塞一直到空间可用或者mq_send()被信号中断。如果空间可用时,多于一个进程在等待发送则按优先级,等待最久的进程先发送它的信息。如果O_NONBLOCK被设定,并且队列已满,则函数返回error。

  该函数接受mqdes确定的消息队列中最久优先级最高的消息,对参数值的限制同上。所选消息从队列移出,复制到msa_ptr指向的缓冲区。如果参数msg_prio不为空,则指定消息被存储在msa_prio所引用的地方。如果消息队列为空,并且O_NONBLODK没有设定,该函数阻塞直到消息排列入队列中或者该函数被信号中断。当有多个进程在消息到达队列后请求接受,则优先级原则与上相同。

  如果参数notification不为空,函数记录下调用进程被通知空的消息队列(由消息队列描述符mqdes相联)中有一条消息到来。当消息队列从空到非空时,一条通知消息将发送到进程中,在任一时刻,只有一个通知消息被一个消息队列记录。如果notifiction为空并且进程当前被指定的队列记录,则已存在的记录被移去。

  PTHREAD_PRIO_NONE:线程的优先级和调度不会受到互斥锁拥有权的影响。

  PTHREAD_PRIO_PROTECT:当线程拥有一个或多个使用初始化的互斥锁属性时,此协议值会影响其他线程的优先级和调度。

  pthread_mutexattr_setprioceiling()可用来设置互斥锁属性对象的优先级上限属性。prioceiling 指定已初始化互斥锁的优先级上限。优先级上限定义执行互斥锁保护的临界段时的最低优先级。prioceiling 位于 SCHED_FIFO 所定义的优先级的最大范围内。要避免优先级倒置,请将 prioceiling 设置为高于或等于可能会锁定特定互斥锁的所有线程的最高优先级。oldceiling 包含以前的优先级上限值。

  如果针对以前初始化的但尚未销毁的互斥锁调用 pthread_mutex_init(),则该互斥锁不会重新初始化。如果属主无法使状态保持一致,请勿调用 pthread_mutex_init(),而是解除锁定该互斥锁。在这种情况下,所有等待的线程都将被唤醒。以后对 pthread_mutex_lock() 的所有调用将无法获取互斥锁,并将返回错误代码 ENOTRECOVERABLE。现在,通过调用 pthread_mutex_destroy() 来取消初始化该互斥锁,即可使其状态保持一致。调用 pthread_mutex_init() 可重新初始化互斥锁。

  锁操作主要包括加锁pthread_mutex_lock()、解锁 pthread_mutex_unlock()和测试加锁 pthread_mutex_trylock()三个,不论哪种类型的锁,都不可能被两个不同的线程同时得到,而必须等待解锁。对于普通锁和适应锁类型, 解锁者可以是同进程内任何线程;而检错锁则必须由加锁者解锁才有效,否则返回EPERM;对于嵌套锁,文档和实现要求必须由加锁者解锁。在同一进程中的线程,如果加锁后没有解锁,则任何其他线程都无法再获得锁。pthread_mutex_trylock()语义与pthread_mutex_lock()类似,不同的是在锁已经被占据时返回EBUSY而不是挂起等待。

  线程具有属性,用pthread_attr_t()表示,在对该结构进行处理之前必须进行初始化,在使用后需要对其去除初始化。我们用pthread_attr_init()函数对其初始化,用pthread_attr_destroy()对其去除初始化。调用pthread_attr_init()之后,pthread_t结构所包含的内容就是操作系统实现支持的线程所有属性的默认值。

  线程的分离状态决定一个线程以什么样的方式来终止自己。在默认情况下线程是非分离状态的,这种情况下,原有的线程等待创建的线程结束。只有当pthread_join()返回时,创建的线程才算终止,才能释放自己占用的系统资源。

  而分离线程不是这样子的,它没有被其他的线程所等待,自己运行结束了,线程也就终止了,马上释放系统资源。程序员应该根据自己的需要,选择适当的分离状态。所以如果我们在创建线程时就知道不需要了解线程的终止状态,则可以pthread_attr_t结构中的detachstate线程属性,让线程以分离状态启动。

  这两个函数具有两个参数,第1个是指向属性对象的指针,第2个是继承性或指向继承性的指针。继承性决定调度的参数是从创建的进程中继承还是使用在schedpolicy和schedparam属性中显式设置的调度信息。Pthreads不为inheritsched指定默认值,因此如果你关心线程的调度策略和参数,必须先设置该属性。

  如果你需要显式的设置一个线程的调度策略或参数,那么你必须在设置之前将inheritsched属性设置为PTHREAD_EXPLICIT_SCHED.线) 线程属性的调度策略

  这两个函数具有两个参数,第1个参数是指向属性对象的指针,第2个参数是调度策略或指向调度策略的指针。调度策略可能的值是先进先出(SCHED_FIFO)、轮转法(SCHED_RR),或其它(SCHED_OTHER)。

  SCHED_FIFO策略允许一个线程运行直到有更高优先级的线程准备好,或者直到它自愿阻塞自己。在SCHED_FIFO调度策略下,当有一个线程准备好时,除非有平等或更高优先级的线程已经在运行,否则它会很快开始执行。

  SCHED_RR(轮循)策略是基本相同的,不同之处在于:如果有一个SCHED_RR

  策略的线程执行了超过一个固定的时期(时间片间隔)没有阻塞,而另外的SCHED_RR或SCHBD_FIPO策略的相同优先级的线程准备好时,运行的线程将被抢占以便准备好的线程可以执行。

  当有SCHED_FIFO或SCHED_RR策赂的线程在一个条件变量上等持或等持加锁同一个互斥量时,它们将以优先级顺序被唤醒。即,如果一个低优先级的SCHED_FIFO线程和一个高优先织的SCHED_FIFO线程都在等待锁相同的互斥且,则当互斥量被解锁时,高优先级线程将总是被首先解除阻塞。

  这两个函数具有两个参数,第1个参数是指向属性对象的指针,第2个参数是sched_param结构或指向该结构的指针。

  注意:如果不是编写实时程序,不建议修改线程的优先级。因为,调度策略是一件非常复杂的事情,如果不正确使用会导致程序错误,从而导致死锁等问题。如:在多线程应用程序中为线程设置不同的优先级别,有可能因为共享资源而导致优先级倒置。

  这两个函数用于获取和设置堆栈大小属性。stacksize属性定义系统分配的栈大小(以字节为单位),size不应小于系统定义的最小栈大小。

  这两个函数分别用来设置和得到线程的作用域。attr是线程属性变量,scope是线程的作用域。若成功返回0,若失败返回-1。作用域控制线程是否在进程内或在系统级上竞争资源,可能的值是:PTHREAD_SCOPE_PROCESS(进程内竞争资源)、PTHREAD_SCOPE_SYSTEM(系统级竞争资源)。

  pthread_create是创建线,否则返回出错编号。thread为指向线程标识符的指针。attr用来设置线程属性。第三个参数是线程运行函数的起始地址。arg是运行函数的参数。

  该函数将子线程的状态设置为分离的,则该线程运行结束后会自动释放所有资源。

  pthread_join()使一个线程等待另一个线程结束。代码中如果没有pthread_join主线程会很快结束从而使整个进程结束,从而使创建的线程没有机会开始执行就结束了。加入pthread_join后,主线程会一直等待直到等待的线程结束自己才结束,使创建的线) 获得线程自身ID

  该函数获得线程自身的ID。pthread_t的类型为unsigned long int,所以在打印的时候要使用%lu方式,否则将产生奇怪的结果。

  前面的那些函数pthread_attr_setschedparam()与pthread_attr_getschedparam()只能通过线程的属性对象pthread_attr_t来设置线程的调度策略和优先级,不能够直接设置正在运行的线程的调度策略和优先级,而这两个函数可以直接设置。

  在默认情况下,线程的终止状态会保存到对该线程调用pthread_join(),如果线程已经处于分离状态,线程的底层存储资源可以再线程终止时立即被收回。当线程被分离时,并不能用pthread_join()函数等待它的终止状态。对分离状态的线程进行pthread_join()的调用可以产生失败,返回EINVAL。pthread_detach()调用可以用于是线程进入分离状态。[apue]

  这两个函数用于创建和销毁条件变量属性对象。若成功返回0,若失败返回错误编号。一旦某个条件变量对象被初始化了,我们就可以利用下面函数来查看或修改特定属性了。

  条件变量使用之前必须首先进行初始化,pthread_cond_t数据类型代表的条件变量可以用两种方式进行初始化,可以把常量PTHREAD_COND_INITIALIZER赋给静态变量分配的条件变量,但是如果条件变量时动态分配的,可以使用pthread_cond_init函数进行初始化。在释放底层的内存空间之前,可以使用pthread_cond_destroy()函数对条件变量进行去除初始化。

  pthread_cond_signal()作用是发送一个信号给另外一个正在处于阻塞等待状态的线程,使其脱离阻塞状态,继续执行.如果没有线程处在阻塞等待状态,pthread_cond_signal也会成功返回。应该在互斥量被锁定后调用。若不止一个线程阻塞在条件变量上,则应用pthread_cond_broadcast()向其它所以线) 等待(阻塞)

  使用pthread_cond_wait()等待条件变为真,如果再给定的时间内条件不能满足,那么会生成一个代表出错码的返回变量。传递给pthread_cond_wait()的互斥量对条件进行保护,调用者把锁住的互斥量传给函数,函数把调用线程放到等待条件的线程列表上,然后对互斥量解锁,这两个操作室原子操作。这样就关闭了条件检查的线程和线程进入休眠状态等待条件改变着两个操作之间的时间通道,这样线程就不会错过条件的任何变化。pthread_cond_wait()返回时,互斥量再次被锁住。

本文链接:http://chuyenchame.com/duruyuanyu/602.html