建网站的公司 快云深圳光明区最新消息

web/2025/10/2 11:33:30/文章来源:
建网站的公司 快云,深圳光明区最新消息,微信公小程序开发教程,威海微网站建设线程概述 线程#xff08;thread#xff09;技术早在60年代就被提出#xff0c;但真正应用多线程到操作系统中去#xff0c;是在80年代中期#xff0c;solaris是这方面的佼佼者。传统的Unix也支持线程的概念#xff0c;但是在一个进程#xff08;process#xff09;中只… 线程概述 线程thread技术早在60年代就被提出但真正应用多线程到操作系统中去是在80年代中期solaris是这方面的佼佼者。传统的Unix也支持线程的概念但是在一个进程process中只允许有一个线程这样多线程就意味着多进程。现在多线程技术已经被许多操作系统所支持包括Windows/NT当然也包括Linux。   为什么有了进程的概念后还要再引入线程呢使用多线程到底有哪些好处什么的系统应该选用多线程我们首先必须回答这些问题。   使用多线程的理由之一是和进程相比它是一种非常节俭的多任务操作方式。我们知道在Linux系统下启动一个新的进程必须分配给它独立的地址空间建立众多的数据表来维护它的代码段、堆栈段和数据段这是一种昂贵的多任务工作方式。而运行于一个进程中的多个线程它们彼此之间使用相同的地址空间共享大部分数据启动一个线程所花费的空间远远小于启动一个进程所花费的空间而且线程间彼此切换所需的时间也远远小于进程间切换所需要的时间。据统计总的说来一个进程的开销大约是一个线程开销的30倍左右当然在具体的系统上这个数据可能会有较大的区别。   使用多线程的理由之二是线程间方便的通信机制。对不同进程来说它们具有独立的数据空间要进行数据的传递只能通过通信的方式进行这种方式不仅费时而且很不方便。线程则不然由于同一进程下的线程之间共享数据空间所以一个线程的数据可以直接为其它线程所用这不仅快捷而且方便。当然数据的共享也带来其他一些问题有的变量不能同时被两个线程所修改有的子程序中声明为static的数据更有可能给多线程程序带来灾难性的打击这些正是编写多线程程序时最需要注意的地方。   除了以上所说的优点外不和进程比较多线程程序作为一种多任务、并发的工作方式当然有以下的优点   1) 提高应用程序响应。这对图形界面的程序尤其有意义当一个操作耗时很长时整个系统都会等待这个操作此时程序不会响应键盘、鼠标、菜单的操作而使用多线程技术将耗时长的操作time consuming置于一个新的线程可以避免这种尴尬的情况。   2) 使多CPU系统更加有效。操作系统会保证当线程数不大于CPU数目时不同的线程运行于不同的CPU上。   3) 改善程序结构。一个既长又复杂的进程可以考虑分为多个线程成为几个独立或半独立的运行部分这样的程序会利于理解和修改。 一个线程所包含的信息呈现出了它在一个进程中的执行环境它们包括线程ID线程栈时刻优先级和策略a scheduling priority and policy信号屏蔽字error变量以及线程相关的特定数据线程私有数据。在一个进程中几乎所有的东西都是可以共享的包括代码段全局变量以及堆、栈还包括文件描述符等。一个线程的线程ID是用于在进程中唯一确定的标识和进程ID不同它只有在该线程所在的进程中才有意义。 线程的创建 首先我们来看一下调用函数 [cpp] view plaincopy int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr,            void *(*start_rtn)(void), void *restrict arg);   它的第一个参数是O类型的用于获取新创建的线程IDattr是线程属性默认时可赋值为空start_rtn是一个函数指针线程创建成功后该函数将作为线程的入口函数开始运行arg是传递给该线程函数的参数。 新创建的线程有权访问它所在进程的地址空间它将继承父线程的浮点环境floating-point environment以及信号屏蔽字不过已经处于阻塞队列中的信号将被清空。 新创建的线程默认将以分离模式运行也就是说当线程结束时系统将自动回收其资源并扔掉其结束状态。当然我们也可以通过设置其线程属性来使线程以非分离模式运行在此模式下线程结束时必须由其他线程调用join函数来释放其资源并获取其结束状态。 我们来看看线程属性的设置方式以下两个函数用于初始化以及销毁线程属性结构体并非释放内存 [cpp] view plaincopy int pthread_attr_init(pthread_attr_t *attr);// 将属性结构体初始化为默认值   int pthread_attr_destroy(pthread_attr_t *attr);   这样在初始化后属性结构体就被初始化为默认值下面的函数可用于获取以及设置线程的分离属性 [cpp] view plaincopy int pthread_attr_getdetachstate(const pthread_attr_t *restrict attr, int *detachstate);   int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);   在设置时第二个参数分离状态只能是这两种常量PTHREAD_CREATE_DETACHED分离模式和PTHREAD_CREATE_JOINABLE。 当然我们也可以在运行期间修改线程的分离属性以下函数可以在线程运行时将其改变为分离模式 [cpp] view plaincopy int pthread_detach(pthread_t thread);   线程属性不止用于分离属性我们知道由于所有的线程都使用同一个地址空间每一个线程栈的大小就受到了限制根据应用的业务逻辑我们可能需要修改一个线程的栈的默认大小例如当存在的线程过多我们就希望它的栈能够小一点而如果某个线程将要执行的业务逻辑需要进行很深的递归调用我们就希望其运行栈能够大一点。通过修改属性的方式也能对这些进行设置 [cpp] view plaincopy int pthread_attr_getstack(const pthread_attr_t *restrict attr,        void **restrict stackaddr, size_t *restrict stacksize);   int pthread_attr_setstack(const pthread_attr_t *attr,        void *stackaddr, size_t *stacksize);   stackaddr是栈的首地址stacksize则是栈的大小。当然许多时候我们不希望自己来处理内存的分配等事宜也可以通过以下的函数只指定栈的大小 [cpp] view plaincopy int pthread_attr_getstacksize(const pthread_attr_t *restrict attr,       size_t *restrict stacksize);   int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);   一个属性对象在被设置之后可以用于多个线程的创建同时当属性对象使用完毕后我们再对属性对象的更改或是destroy都不会影响到那些已经创建完成的线程。 线程终止 以下是线程正常终止的三种方式 1. 线程从线程入口函数处返回其返回值将是该线程的终止状态。 2. 线程调用pthread_exit函数终止当前线程该函数的参数将被作为终止状态。 3. 该线程被相同进程中的其他线程所取消。 由于任意一个线程调用exit系列函数都将终止整个进程因此当我们只想要终止线程时可以使用pthread_exit函数 [cpp] view plaincopy void pthread_exit(void *rval_ptr);   如果线程被取消了则其终止状态将是PTHREAD_CANCELED。那么我们该如何获得线程的终止状态呢前面我们讲过线程的两种运行模式分离模式和接合join模式。当处于分离状态终止时其终止状态将自动被系统所舍弃只有处于接合模式下我们才能获得其终止状态参看以下函数 [cpp] view plaincopy int pthread_join(pthread_t thread, void **rval_ptr);   这个方法将阻塞直到它所指定的线程终止参数rval_ptr是O类型的用于获取线程的终止状态。 类似于atexit函数一样我们也可以为线程提供清理函数以下是线程清理函数的注册函数 [cpp] view plaincopy void pthread_cleanup_push(void (*rtn)(void *), void *arg);   void pthread_cleanup_poppthread_cleanup_pop(int execute);   这两个函数分别用于增加与删除清理函数清理函数可以不止一个其组织形式按照栈的结构组织所以增加删除都是在栈顶操作并且其调用顺序也是与其添加顺序相反的。出口函数在以下三种情况下会被调用 1. 调用pthread_exit函数 2. 响应对线程的取消请求 3. 使用非0参数调用pthread_cleanup_pop函数。 从上面可以看出来有一点也许会另我们意外那就是当线程从入口函数处正常返回时清理函数并不会得到调用。 pthread_cleanup_push用于增加清理函数我们来看一下pthread_cleanup_pop函数它的作用是删除最后一个被注册的清理函数如果其调用参数非0,那么在删除该清理函数的同时它也将得到调用。有一点需要注意的是由于pthread_cleanup_push和pthread_cleanup_push可能被宏来实现所以我们必须成对的使用它们否则会报编译错误。下面是linux的实现方式 [cpp] view plaincopy #  define pthread_cleanup_push(routine, arg) \   do {                                        \   __pthread_cleanup_class __clframe (routine, arg)      #  define pthread_cleanup_pop(execute) \   __clframe.__setdoit (execute);                        \   } while (0)   线程取消cancellation [cpp] view plaincopy int pthread_cancel(pthread_t tid);   该函数的默认效果是取消tid线程这使得该线程仿佛自己调用了pthread_exit使用PTHREAD_CANCELED作为其结束状态。不过实际上一个线程不必马上对该取消请求进行响应甚至可以忽略该请求。 在默认情况下只有当线程运行到取消点cancellation point时才会对取消请求进行响应一个取消点是指线程检查其是否已经被取消的地方POSIX.1定义了如下的一些函数作为取消点当这些函数被调用时将检查是否被取消从而作出响应 当然还有一些其他的函数也有可能作为取消点不过那些是可选的依照具体的实现而不同不具备可移植性。实际上我们也可以自己定义取消点。请看下面的函数 [cpp] view plaincopy void pthread_testcancel(void);   当取消请求发生时默认情况下它会被阻塞直到线程对它进行响应该函数调用时如果已有取消请求被阻塞住并且线程取消功能并没有被关闭这个等会儿解释的话该线程将被取消。 前面说的这些都是默认操作实际上我们也可以修改取消的状态和类型。先说取消类型cancellation type通过对该属性进行设置可以决定线程是否在取消点才被取消请看函数声明 [cpp] view plaincopy int pthread_setcanceltype(int type, int *oldtype);   type参数只能是如下常量之一PTHREAD_CANCEL_DEFERRED这个是默认的 or PTHREAD_CANCEL_ASYNCHRONOUS。使用第一个常量则线程只有到取消点才会检查取消请求但后者则决定线程可以在任何时候被取消不必等到取消点。oldtype是一个O类型参数用于获取历史取消类型。 我们也可以修改其取消状态使线程忽略其他线程的取消请求使用如下函数 [cpp] view plaincopy int pthread_setcancelstate(int state, int *oldstate);   通过此函数可以设置线程是否对线程取消进行响应state只能是如下常量之一PTHREAD_CANCEL_ENABLE 或是 PTHREAD_CANCEL_DISABLE。需要注意的是当取消状态被设置为PTHREAD_CANCEL_DISABLE时取消请求并没有被舍弃它只是被阻塞住了直到当该功能再此被启用时如果有阻塞的取消请求线程将会被取消。 多线程下的信号量机制 每一个线程都有它自己的信号量屏蔽字但是信号处理方式signal disposition却是在进程内共享的。如果一个信号量是有硬件错误或是时钟到点导致的那么该信号将被发送给发生这些事件的线程而如果不是这些情况引发的信号它们将被发送给该进程下的任意一个线程。在多线程环境下使用sigprocmask函数修改信号屏蔽字的行为是未定义的我们应该使用另外一个函数代替那就是pthread_sigmask。 [cpp] view plaincopy int pthread_sigmask(int how, const sigset_t *restrict set, sigset_t *restrict oset);   他的使用方式和sigprocmask函数是一致的这里就不再多作讨论了。 在多线程环境下我们通常可以指定某个特定的线程来专门完成信号处理的工作从而可以防止因其他工作线程被打断而引发的异常情况先来看一个函数 [cpp] view plaincopy int sigwait(const sigset_t *restrict set, int *restrict signop);   set参数的类型是我们前面将信号机制时所提到过的信号集在这里它被用来指定我们想要处理的信号而第二个参数是O类型参数当该函数返回时它存有我们实际接收到的信号number。当该函数调用后线程会被阻塞直到有它所等待的信号发生实际上该函数也是可能会被其他信号所中断的。如果在调用时已经有它要等待的信号在阻塞队列里了那么该函数将立即返回而不需要再阻塞。在返回之前sigwait函数将移除掉阻塞队列中它所等待的信号。为避免可能出现的空档造成错误的信号处理行为线程在调用sigwait函数之前应该先把它要等待的信号给阻塞调。而在掉用sigwait函数的时候它将自动unblock这些信号并开始等待直到那些信号中的一个被交付。在该函数返回以前这些被unblock了的信号会被再次自动恢复阻塞。如果多个线程在调用wigwait时等待了相同的信号当该信号发生后只有一个线程会获得该信号并从阻塞中返回。 在linux的实现中必须要注意的是由于linux中实际上没有真正的线程它所谓的线程实际上只是一个轻量级的进程所以当信号发生时如果主线程没有阻塞这个信号其他线程是sigwait不到那个信号的。因此在使用sigwait函数时我们最好让其他线程都把那些信号都给阻塞住。 实际上我们也可以将信号发送给某个特定的线程类似于kill其函数声明如下 [cpp] view plaincopy int pthread_kill(pthread_t thread, int signo);   该函数的作用就是向指定的线程发送指定的信号量这里有一个小技巧当我们指定信号量为0时该函数可以用来检测该线程是否存在。如果接受到信号的线程对信号的默认操作是终止进程的话那么整个进程都将被终止。 对于信号量还有一点值得注意的是alarm timers是属于进程的资源所有的线程都共享了同一个alarm所以对于同一个进程中的多个线程来说不用担心其他线程的干扰而使用alarm timers的方法是不存在的。 参考文献 《Linux下的多线程编程》 姚继锋

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/85593.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

珠海网站制作策划企业网站建设招标

wcf:rest介绍 管理多个资源之间的关系可能是RESTful API的重要组成部分。 在这篇文章中,我们将看到使用REST API可以管理多对多关系。 我们以一个简单的用户 / 组关系为例。 假设用户和组是两个单独的资源(例如/ users和/ groups )&#xff…

网站ftp怎么登陆快车app官方下载

AI大模型的一个痛点就是训练数据有截止日期,例如chatgpt的训练数据截止日期是2021年10月。这导致模型回答截止日期之后产生的新闻事件或者专业知识时不够准确。 将AI和搜索引擎结合起来,似乎是一种解决方式。 目前,国内外公布了不少AI搜索引…

无锡h5网站建设网站必须做301重定向吗

1. 日常生活中的应用 智能家居 场景描述:智能家居系统通过集成各种设备的API接口,实现远程控制和自动化。例如,通过API接口,用户可以通过手机应用控制家中的灯光、温度、安防系统等。案例:某智能家居品牌通过集成智能…

windows10php网站建设在线视频直播网站建设

guava集合操作类的使用我目前正在为LibFX添加一项新功能,为此我创建了一些类似于Java Collections Framework的自定义集合。 我一直在寻找可以与之对抗的测试,并很高兴发现Google的Guava包含了我所需要的:一个庞大的测试套件,可以…

自适应型网站建设服务电话wordpress创建公告

目录 1、使用SPY查看窗口的信息 2、使用SPY查看某些软件UI窗口用什么UI组件实现的 2.1、查看海康视频监控客户端安装包程序 2.2、查看华为协同办公软件WeLink 2.3、查看字节协同办公软件飞书 2.4、查看最新版本的Chrome浏览器 2.5、查看小鱼易连视频会议客户端软件 2.6…

个人网站推广 公司上海网页设计公司选择兴田德润

centos7虚拟机和docker的安装:可以参考之前的博文 CPU、mysql-exporter、docker监控模板:百度网盘 提取码:0000 先查看服务器时间是否和当前时间一致,如果不一致,查看对应设置:centos7时间同步博文 一、…

湖北网站注册设计公司河北省市场监督管理局

来源:智造智库工业4.0在德国被认为是第四次工业革命,主要是指,在“智能工厂”利用“智能备”将“智能物料”生产成为“智能产品”,整个过程贯穿以“网络协同”,从而提升生产效率,缩短生产周期,降…

网络营销的网站的分析网站html5模板

注意:本文不仅含有SpringBoot中常见的注解,还有其它框架的注解。因为注解之间会相互配合使用,所以每一个注解的示例与其他的注解都会有部分相似,请选择查看。 文章目录 01、SpringBootApplication02、Configuration03、EnableAuto…

自适应网站 与响应式贵阳做网站 优帮云

关于String不可变的问题:从毕业面试到现在,一个群里讨论的东西,反正码农面试啥都有,这也是我不咋喜欢面试代码,因为对于我而言,我并不喜欢这些面试。知道或不知道基本没啥含氧量,就是看看源代码…

惠州网站营销推广网站哪里可以做

点击蓝字关注我们AI研习图书馆,发现不一样的世界风格迁移图像风格化迁移是一个很有意思的研究领域,它可以将一张图的风格迁移到另外一张图像上,由此还诞生了Prisma和Ostagram这样的商业化产品。本文,我们将介绍谷歌大脑团队的一篇…

建设网站成本预算开发公司网签物料

LabVIEW开发航天器动力学与控制仿真系统 计算机仿真是工程设计和验证的非常有用的工具。它节省了大量的时间、金钱和精力。航天器动力学与控制仿真系统由LabVIEW程序开发,它是模拟航天器等动态系统的有用工具。还可轻松与硬件连接并输出真实信号。 项目采用系统工…

绵阳做手机网站建设如何建立自己推广网站

功能介绍 Oracle数据库在创建sequence的时候可以支持设置nomaxvalue,这样的SQL在LightDB 23.3版本之前都是执行失败的。为了方便Oracle用户迁移到LightDB上,在LightDB 23.3版本上,增加了sequence支持设置nomaxvalue的语法兼容。 nomaxvalue内…

彩票网站开发制作网页简单制作流程

我想知道怎么求N的N次方&#xff0c;这个数据是很大的&#xff0c;但是我要的是这个数据的最高位的数&#xff0c;应该有什么好的方法吧&#xff01; 请大侠们帮帮忙吧&#xff01;&#xff01;&#xff08;N <1000000000&#xff09; 这个问题提出后&#xff0c;fallening同…

电商网站开发教程网站备案号怎么查

我同意TigerhawkT3&#xff08;1&#xff09;你教授对pick_color()的实现是垃圾。但我不认为random.choice()&#xff0c;或者你教授滥用random.shuffle()的方式是最好的选择。两者的问题是&#xff0c;在连续调用时可以获得相同的颜色&#xff0c;这是在正方形内绘制正方形时不…

网页游戏网站官网网站怎么做推广和宣传

1.枚举 枚举是一种特殊类 2.枚举类的格式 注意&#xff1a; ①枚举类中的第一行&#xff0c;只能写一些合法的标识符(名称)&#xff0c;多个名称用逗号隔开。 ②这些名称&#xff0c;本质是常量&#xff0c;每个常量都会记住枚举类的一个对象。 3.枚举类的特点 ①枚举类的…

上海高端网站建设公司网站 keywords

发布时间&#xff1a;2017-05-12我的世界战舰设计图 手机版战舰怎么做.那下面给大家分享的是玩家自己在手机版中手撸的一个战舰建筑哦~那感兴趣的玩家不妨进来看看他是怎么建造战舰的哦~希望大家喜欢. 游戏园我的世界官方群:325049520 二群:25607 ...标签&#xff1a;我的世界 …

免费制作app生成器网站济南网站建设运营

osgi架构与linux在构建可扩展&#xff0c;可靠的分布式系统的背景下&#xff0c;“模块化”和“微服务体系结构”这两个术语如今经常出现。 众所周知&#xff0c;Java平台本身在模块化方面很弱&#xff08; Java 9将通过交付Jigsaw项目来解决此问题&#xff09;&#xff0c;这为…

网站建设公司专业网站开发需求企业电话认证

Linux mesg命令介绍 Linux mesg命令用于设置终端机的写入权限。当mesg设置为y时&#xff0c;其他用户可以利用write指令将信息直接显示在您的屏幕上。如果设置为n&#xff0c;则不允许其他用户将信息直接显示在你的屏幕上。 Linux mesg命令适用的Linux版本 mesg命令在大多数…

电商网站的建设与安全wordpress关闭分享

官方提供的教程介绍了通过钉钉、微信等工具接收短信验证码的方法&#xff0c;但最终实现的目的是获取验证码&#xff0c;而不是通过工具间接获得。 因此&#xff0c;我们可以直接调用API接口来获取验证码&#xff0c;从而达到更快、更便捷地获得验证码的目的。 所以做了一个服…

网页设计作业欣赏seo会被取代吗

注&#xff1a;本文写的内容全部在ubuntu12.04下完成。要在linux下写C程序&#xff0c;要懂的一点编译的知识。下面介绍一下。源代码->预处理器(负责将代码补充)->汇编程序(生成汇编语言)-> 目标程序(生成二进制文件)->链接器(链接文件)->可执行程序(生成执行程…