当前位置: 首页 > news >正文

长沙网站建设费用手机做服务器建网站

长沙网站建设费用,手机做服务器建网站,网站风格的设计原则,注册公司名字有没有重复在哪可以查目录 ​编辑 1.什么是进程#xff0c;线程#xff0c;并发#xff0c;并行 优点 缺点 什么资源是线程应该私有的呢 为什么线程切换成本更低呢 3.线程控制 pthread_create lpthread选项 makefile 代码实现 ps -aL 什么是LWP 轻量级进程ID与进程ID之间的区别 LWP与pthr…目录 ​编辑 1.什么是进程线程并发并行 优点 缺点 什么资源是线程应该私有的呢 为什么线程切换成本更低呢 3.线程控制 pthread_create lpthread选项 makefile 代码实现 ps -aL 什么是LWP 轻量级进程ID与进程ID之间的区别 LWP与pthread_create创建的线程之间的关系 4.线程中止,等待,分离 pthread_exit函数 pthread_cancel函数  线程等待 pthread_join​编辑 线程分离  pthread_detach 5.线程互斥 进程线程间的互斥相关背景概念 多线程共享资源访问的不安全问题举个抢票的例子 锁 互斥量的接口 今天推荐一首歌曲  黄昏      周传雄 依然记得从你口中~ 说出再见坚决如铁~ 昏暗中有种烈日灼身的错觉~ 黄昏的地平线~ 划出一句离别~ 爱情进入永夜~ 开始我们的学习吧 1.什么是进程线程并发并行 进程是资源分配的最小单位有独立的地址空间和系统资源。线程是cpu调度程序执行的最小单位一个线程只属于一个进程而一个进程可以有多个线程多个线程共享同一个进程的资源。在多核系统下允许几个线程各自独立的在处理器上运行操作系统提供线程就是为了方便有效地实现这种并发性。 一切进程至少都有一个执行线程 线程在进程内部运行本质是在进程地址空间内运行 在Linux系统中在CPU眼中看到的PCB都要比传统的进程更加轻量化 多进程同时运行QQ、微信、浏览器 多线程 用浏览器同时进行浏览网页、播放视频 并发是把cpu运行时间划分成若干个时间段每个时间段再分配给各个线程执行 当一个线程在运行时其他线程处于挂起状态。 并行是同一时刻当一个cpu执行一个线程时另一个cpu可以执行另一个线程两个线程互不抢占cpu资源是真正意义上的 不同线程在同一时刻同时执行 形象地解释 进程是拥有一系列资源的集合这些资源包括内存空间、内核对象、资源文件等等。我们将进程理解为一个工厂工厂本身不能运作需要有人来操作。那么这些工人就是线程每一个工人操作自己的一台设备这个设备就可以看成是线程的栈他由这个工人自己使用。一个工厂里有多台设备时如果只有一个人那么他就需要去一个个的去操作工厂里的设备如果这些设备需要同时运行那么这样操作效率太低。因此工厂会多聘用几个工人他们每个人操作自己的设备这样效率就会大大提高。工人在操作设备时可能两个人需要使用同一个工具这个工具是全局的变量因此他们可以共同访问但是一个工人要去使用这个工具时他会等在那里等另一个人使用完然后他就可以接过工具继续干活了这就是线程的同步。创建多个工厂就是多进程程序。工人操作的每台设备还是属于该工厂因此线程是依附于进程的占用进程的地址空间线程之间也可以相互访问对方的地址需要通过传址能实现但是一般不会出现这样的情况试想能有多大的机会在一个函数中访问另一个函数的的局部变量。在代码的实现中我们可以将线程仅仅看成一函数去分析只不过他是并发进行的。 工厂就是进程工人就是线程工厂所占的位置就是进程空间工厂里的设备和工具就是数据和资源多个工人同时工作就是多线程几个工人要用同时使用一个工具就是线程同步。 重点 进程是资源分配的基本单位线程是调度的基本单位 线程独有栈寄存器信号屏蔽字errno...等信息因此各个线程各自有各自的栈区但是堆区共用 任何一个线程都可以创建或撤销另一个线程 进程比线程安全的原因是每个进程有独立的虚拟地址空间 Linux内核中有没有真正意义上的线程呢没有linux用进程的PCB来模拟线程是完全属于自己实现的一套方案 站在CPU的角度来看每一个PCB都可以称之为轻量级进程因为它只需要PCB即可而进程承担分配的资源更多量级更重 Linux线程是CPU调度的基本单位进程是承担分配系统资源的基本实体 2.线程的优缺点 优点 缺点 什么资源是线程应该私有的呢 重要的两点 线程的上下文结构也必须是线程的私有资源。寄存器 每个线程都有自己的私有栈结构   为什么线程切换成本更低呢 3.线程控制 在Linux下PCB其他OS内的PCB进程控制块  Linux下的进程统称为轻量级进程 pthread_create pthread_create是创建线程的一个接口 返回值成功返回0   失败返回错误码 lpthread选项 如果在编译时不带-lpthread选项可以看到g报错pthread_create()函数未定义其实就是因为链接器链接不上具体的动态库此时就可以看出来linux内核中并没有真正意义的线程他无法提供创建线程的接口而只能通过第三方库libpthread.so或libpthread.a来提供创建线程的接口。  makefile //编写makefile 带上 -lpthread test:test.cppg -o $ $^ -stdc11 -lpthread .PHONY:clean clean:rm -f test代码实现 #include iostream #include pthread.h #include unistd.husing namespace std;void *threadRoutine(void *args)//新线程回调在这里 { while(true) { cout新线程(char*)args running... endl; sleep(1); }}int main() {pthread_t tid; //创建线程pthread_create(tid,nullptr,threadRoutine,(void*)thread 1);//进程的名字//下面是主线程 while(true) { coutmain线程 running... endl; sleep(1); } } ps -aL ps命令用于查看进程信息其中-L选项用于查看轻量级进程信息 pthread_self() 用于获取用户态线程的tid而并非轻量级进程ID getpid() 用于获取当前进程的id,而并非某个特定轻量级进程 通过ps -aL就可以看到正在运行的线程有哪些可以看到有两个标识符一个是PID一个是LWP(light weight process)所以CPU在调度那么多的PCB时其实是以LWP作为每个PCB的标识符以此来区分进程中的多个轻量级进程。 主线程的PID和LWP是相同的所以从CPU调度的角度来看如果进程内只有一个执行流那么LWP和PID标识符对于CPU来说都是等价的但当进程内有多个执行流时CPU是以LWP作为标识符来调度线程而不是以PID来进行调度。 什么是LWP LWP轻量级进程是操作系统中用于调度和管理线程的内核层面的实体。 LWP是轻量级进程在Linux下进程是资源分配的基本单位线程是cpu调度的基本单位而线程使用进程pcb描述实现并且同一个进程中的所有pcb共用同一个虚拟地址空间因此相较于传统进程更加的轻量化 轻量级进程ID与进程ID之间的区别 概念 进程IDPID是操作系统为每个正在运行的进程分配的唯一标识符。它是在进程创建时由操作系统分配的并在整个进程的生命周期中保持不变。轻量级进程IDLWP ID是在多线程操作系统中用于标识线程或轻量级进程也称为执行上下文的标识符。一个进程可以包含多个轻量级进程并且每个轻量级进程都有自己的LWP ID。 操作方式 对于PID通常可以使用系统调用如fork()和exec()创建新进程或操作现有进程。对于LWP ID通常使用线程库如pthread创建新线程或操作现有线程。一个进程的LWP ID只在该进程内部可见对于其他进程来说是不可见的。 调度与资源分配 操作系统通过PID进行进程调度和资源分配。进程调度通常是基于运行队列中进程的优先级和调度算法来进行决策的。在多线程操作系统中内核会将CPU时间划分给不同的LWP。调度和资源分配是基于LWP而不是整个进程进行的。 上下文切换 在进程切换时操作系统需要保存和恢复整个进程的上下文这包括进程的寄存器状态、打开的文件、堆栈等。在轻量级进程切换时只需要保存和恢复当前线程的上下文这是因为同一进程内的线程共享同一内存空间和打开的文件。 需要注意的是LWP ID是在多线程操作系统中使用的概念而PID是在所有操作系统中都存在的概念。在某些操作系统中LWP ID可能与线程IDTID或任务IDTID等概念等效或相似。 LWP与pthread_create创建的线程之间的关系 LWP轻量级进程与pthread_create创建的线程之间存在一种关系可以理解为LWP是内核层面对线程的调度和管理的实体而pthread_create创建的线程则是用户层面对线程的抽象。 具体来说pthread_create是一个线程库函数用于在用户空间创建一个新的线程。这个线程由操作系统内核分配一个LWP并将其标识为一个用户线程也称为轻量级进程。该LWP会在它所属的进程中与其他LWP共享进程的地址空间、文件描述符等资源。 LWP与pthread_create创建的线程之间的关系可以总结如下 一个进程可以包含多个LWP每个LWP都有一个唯一的LWP ID。每个LWP可以与一个或多个pthread_create创建的线程相关联这些线程共享其所属进程的资源。每个pthread_create创建的线程有自己的线程ID并且在用户层面上可见可以使用线程库提供的函数进行操作和管理。 需要注意的是LWP的创建和管理是由操作系统内核完成的而pthread_create函数是线程库提供的接口它在内部会使用操作系统提供的系统调用来创建和管理LWP。因此对于用户来说他们只需要使用pthread_create接口来创建和操作线程而无需直接与LWP进行交互。 4.线程中止,等待,分离 线程终止总共有三种方式分别为returnpthread_exitpthread_cancel 1. 从线程函数 return 。这种方法对主线程不适用 , 从 main 函数 return 相当于调用 exit 。 exit是中止进程的 2. 线程可以调用 pthread_ exit 终止自己。 3. 一个线程可以调用 pthread_ cance l 终止同一进程中的另一个线程。 pthread_exit函数 那个线程调用pthread_exit函数 那个线程就退出。俗称“谁调用谁退出”  pthread_cancel函数  在有多个线程的情况下主线程调用pthread_cancel(pthread_self()), 则主线程状态为Z 其他线程正常运行 主线程调用pthread_exit只是退出主线程并不会导致进程的退出  线程等待 与进程类似进程退出之后要被等待也就是回收进程的资源否则会出现僵尸进程僵尸的这种状态可以通过ps指令axj选项看到同时会产生内存泄露的问题。 线程终止同样也需要被等待但线程这里没有僵尸线程这样的概念如果不等待线程同样也会造成资源泄露也就是PCB资源未被回收线程退出的状态我们是无法看到的我们只能看到进程的Z状态。 pthread_join 原生线程库给我们提供了对应的等待线程的接口其中join的第二个参数是一个输出型参数在join的内部会拿到线程函数的返回值然后将返回值的内容写到这个输出型参数指向的变量里面也就是写到我们用户定义的ret指针变量里通过这样的方式来拿到线程函数的返回值。 线程分离  若要进行分离推荐创建完线程之后立马设置分离 pthread_detach 新创建出来的线程默认状态是joinable的也就是说你必须通过pthread_join去等待线程否则就会造成内存泄露。 但如果我们压根就不想等待线程那调用pthread_join就是一种负担这个时候我们就可以通过分离线程的手段来告诉操作系统现在我这个线程要和进程分离了我不再共享进程的地址空间了我也不要进程的任何资源了我们俩人以后就形同陌路互不相干了操作系统你现在就把我回收吧我已经和进程没有任何关系了 所以在设置线程为分离状态后操作系统会立即回收线程的所有资源而不需要等待线程自动退出或者是手动来释放资源表示我们现在已经不关心这个线程了 joinable和detach是线程的两个对立的状态一个线程不能既是joinable又是分离的并且如果线程被设置为detach那么就不可以用join来等待线程否则是会报错的 int pthread_detach(pthread_t thread); 5.线程互斥   进程线程间的互斥相关背景概念 临界资源 多线程执行流共享的资源就叫做临界资源 临界区 每个线程内部访问临界资源的代码就叫做临界区 互斥 任何时刻互斥保证有且只有一个执行流进入临界区访问临界资源通常对临界资源起保护作用 原子性 不会被任何调度机制打断的操作该操作只有两态要么完成要么未完成 多线程共享资源访问的不安全问题举个抢票的例子 假设现在有一份共享资源tickets如果我们想让多个线程都对这个资源进行操作也就是tickets- -的操作但下面两份代码分别出现了不同的结果上面代码并没有出现问题而下面代码却出现了票为负数的情况这是怎么回事呢 其实问题产生就是由于多线程被调度器调度的特性导致的。 抢票代码  #includestdio.h #includeunistd.h #includestring.h #includepthread.h #includecstdio #includeiostreamusing namespace std;//加锁保护 //pthread_mutex_t mtx PTHREAD_MUTEX_INITIALIZER; //pthread_mutex_t 是原生线程库提供的一个数据类型int tickets3000; //在并发访问的时候会导致数据不一致的问题void *gettickets(void *args) {(void*)args; //每个线程内部访问临界资源的代码就叫做临界区while(true){//pthread_mutex_lock(mtx); //加锁if(tickets0){usleep(10000);printf(%s:%d\n,(char*)args,tickets);tickets--;// pthread_mutex_unlock(mtx); //解锁}else{// pthread_mutex_unlock(mtx); break;}}return nullptr; }int main() {pthread_t t1,t2,t3;//线程创建pthread_create(t1,nullptr,gettickets,(void*)thread one);pthread_create(t2,nullptr,gettickets,(void*)thread two);pthread_create(t3,nullptr,gettickets,(void*)thread three);//线程等待pthread_join(t1,nullptr);pthread_join(t2,nullptr);pthread_join(t3,nullptr);return 0; } 结果会出现负数多线程在并发访问的时候可能会导致数据不一致的问题 锁 要解决以上问题需要做到三点 代码必须要有互斥行为当代码进入临界区执行时不允许其他线程进入该临界区。 如果多个线程同时要求执行临界区的代码并且临界区没有线程在执行那么只能允许一个线程进入该临界区。 如果线程不在临界区中执行那么该线程不能阻止其他线程进入临界区 要做到这三点本质上就是需要一把锁。Linux上提供的这把锁叫互斥量 谁持有锁谁才能进入临界区你没有锁那就只能在临界区外面乖乖的阻塞等待等待锁被释放然后你去竞争这把锁竞争到就拿着锁进入临界区执行代码竞争不到就老样子继续乖乖的在临界区外面阻塞等待 互斥量的接口 初始化互斥量有两种方法 静态分配: pthread_mutex_t mutex PTHREAD_MUTEX_INITIALIZER 动态分配:  int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr); 参数 mutex要初始化的互斥量 attrNULL 把上面的代码改成这样就不会出现出现负数的问题,这里用的是静态分配  //加锁保护 pthread_mutex_t mtx PTHREAD_MUTEX_INITIALIZER; //pthread_mutex_t 是原生线程库提供的一个数据类型 ,静态int tickets3000; //在并发访问的时候会导致数据不一致的问题void *gettickets(void *args) {(void*)args; //每个线程内部访问临界资源的代码就叫做临界区while(true){pthread_mutex_lock(mtx); //加锁if(tickets0){usleep(10000);printf(%s:%d\n,(char*)args,tickets);tickets--;pthread_mutex_unlock(mtx); //解锁}else{pthread_mutex_unlock(mtx); break;}}return nullptr; }
http://www.zqtcl.cn/news/281637/

相关文章:

  • 网站安全建设必要性网站登录页面
  • 鄂州网站推广做区块链在哪个网站
  • 网站什么内容网站安全性设计
  • 免费动态域名申请seo发布网站
  • 软件毕设代做网站广告设计公司资质
  • 织梦网站模板如何安装网页设计教程心得体会
  • 网站开发 男生网站二维码怎么做的
  • net网站开发教程网站防御怎么做
  • 手机网站设计只选亿企邦哪个选项不属于网络营销的特点
  • 繁昌网站建设如何用易语言做网站
  • 电子商务网站建设财务分析建立网站方法
  • 大专学网站开发wordpress显示数据库请求
  • 诸暨网站制作设计公众号文章怎么导入到wordpress
  • 网站死链怎么办青岛网站制作企业
  • 已经有域名 怎么修改网站网站推广找客户
  • 网站的制作建站人增加网站流量
  • 向国旗致敬做时代新人网站广州网站建设公司排名
  • 阿里云域名怎么做网站对网站进行seo优化
  • 响应式网站建设合同11月将现新冠感染高峰
  • 做网站客户一般会问什么问题百度云网盘资源分享网站
  • 网站设计中超链接怎么做艺术设计
  • 卡盟网站建设wordpress优化代码
  • 做网站需要什么技术员商城型网站开发网站建设
  • discuz做地方门户网站网站大全免费完整版
  • 莆田人做的网站一天赚2000加微信
  • 阿里云网站访问不了怎么办做网站二维码
  • 手机商城网站建设可采用的基本方式有
  • 网站备案管理做广告公司网站建设价格
  • 绵阳专业网站建设公司上海外贸公司排名榜
  • 如何做英文系统下载网站快速排名工具免费