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

做设计的地图网站深圳seo排名优化

做设计的地图网站,深圳seo排名优化,wordpress 远程图片,茶颜悦色vi设计手册0.页表的正确理解 进程地址空间是进程能够使用的资源窗口,而页表则决定了进程实际上拥有的资源。 页表实际上是二级索引,以32位机器为例。内存管理的基本单位是4kb的页框。 一级页表是以地址的高10位为索引,二级页表是以次高10位为2级页表…

0.页表的正确理解

进程地址空间是进程能够使用的资源窗口,而页表则决定了进程实际上拥有的资源。

页表实际上是二级索引,以32位机器为例。内存管理的基本单位是4kb的页框。

一级页表是以地址的高10位为索引,二级页表是以次高10位为2级页表,找到页框的起始地址,最后再以低12位为偏移量找到实际上的物理地址

1. 线程的概念 

进程是承担资源分配的基本实体,线程则是在进程内部的执行单元,是CPU调度的基本单位。

在Linux中并没有真正意义上的线程,有的只是轻量级进程。当我们创建线程时,实际上是在进程内部再创建一个轻量级进程,它与父进程指向同一个mem_struct,使用同一个页表,属于进程的一部分。

 轻量级进程的实现实际上是用进程PCB模拟而来的,因此其具有与PCB相同的被执行,调度的方法。维护成本更低,更加的高效。

Linux只为我们提供了轻量级进程创建的接口,因此在此基础上为我们提供了一套原生线程库,实现了对底层接口的封装。

2.线程资源私有情况

线程之间绝大部分资源共享,但线程之间又有直接的私有空间

1️⃣线程pcb属性信息

2️⃣线程的上下文信息

3️⃣线程的独立栈结构

3.线程切换高效

CPU在处理线程切换时的工作要比进程切换的工作少。

进程切换时需要:切换进程地址空间,切换页表,切换PCB,切换上下文

线程切换时需要:切换PCB,切换上下文

但是最重要的是,进程切换时CPU中的Cache数据需要全部更新,而线程切换时CPU中的Cache数据并不用全部更新。因此线程切换要比进程切换更高效。

4.线程接口

4.1线程创建pthread_create

4.2线程终止

 1️⃣当线程任务结束return后就会终止

2️⃣线程中调用pthread_exit(return val)时也会终止线程

3️⃣线程取消pthread_cancel(tid)时就会终止指定线程此时线程的返回值是(void*)-1

4.3线程等待pthread_join(pthread_t , void **)

与进程等待相同,线程也需要等待,目的是:获取返回值和回收线程的PCB控制块。

4.4线程分离pthread_detach(pthread_t tid)

如果我们不关心线程的返回值,想像进程对SIGCHILD采取SIG_IGN,让子进程自己回收释放时,我们就能使用线程分离,这样线程就能自己回收释放了,此时线程将由joinable变为onjoinable状态,此时的线程将不能被等待。

如果我们想在线程内部时自己detach,那么可以用pthread_self()获取自己的tid。 

 练习代码

#include<cstdio>
#include<iostream>
#include<unistd.h>#include<pthread.h>using namespace std;
void* task(void* arg){int count = 0;const char* tmp = static_cast<const char*>(arg);while(true){printf("this is thread:%s\n",tmp);count++;if(count == 10) break;sleep(1);}pthread_exit((void*)"我是新线程,我结束了");//return (void*)"我是新线程,我结束了";
}int main(){pthread_t tid  = 0;pthread_create(&tid,nullptr,task,(void*)"this is new thread");void* ret = nullptr;int cnt = 5;while(cnt--)  sleep(1);pthread_cancel(tid);    pthread_join(tid,&ret);printf("return val :%d\n",ret);return 0;
}
#include<cstdio>
#include<unistd.h>
#include<pthread.h>
#include<vector>
using namespace std;
// void* task(void* arg){
//     const char* buffer = static_cast<const char*>(arg);
//     while(true){
//         printf("%s\n",buffer);
//         sleep(1);
//     }
//     return nullptr;
// }// int main(){
// #define NUM 10
//     pthread_t array[NUM] ={0};
//     for(int i = 0 ; i < NUM;i++ ){
//         char buffer[1024];
//         snprintf(buffer,sizeof buffer,"thread: %d",i);
//         pthread_t tid = 0;
//         pthread_create(&tid,nullptr,task,buffer);
//         array[i] = tid;
//     }//     for(int i = 0 ; i < NUM; i++){
//         pthread_join(array[i],nullptr);
//     }//     return 0;
// }
//上面的代码是错误的,会导致每个线程都是从9开始访问,因为其传的是地址,而每次for都会更改地址指向内容,而且线程进入的速度不同,导致异常情况void* task(void* arg){const char* buffer = static_cast<const char*>(arg);int cnt = 10;while (cnt--){printf("%s\n",buffer);sleep(1);}return 0;
}
struct thread{pthread_t tid;char buffer[1024];
};
int main(){#define NUM 10vector<thread*> v(NUM);for(int i = 0 ; i < NUM;i++ ){v[i] = new thread;snprintf(v[i]->buffer,sizeof v[i]->buffer,"thread :%d",i);pthread_t tid = 0;pthread_create(&tid,nullptr,task,(void*)v[i]->buffer);printf("%x\n",tid);v[i]->tid = tid;}for(int i = 0 ; i < NUM; i++){pthread_join(v[i]->tid,nullptr);printf("on sucess:%x\n",v[i]->tid);delete v[i];}return 0;
}

5.线程库,tid,独立栈,线程局部存储

我们编写的代码链接线程库时,需要-lphread指定链接的库才能链接成功。

当运行程序后,线程动态库将会加载到进程地址空间的共享区,线程库为我们提供了方法接口。线程的私有数据,例如线程的上下文结构,线程私有栈,线程的局部存储数据都是在mmap分配的。

线程的pthread_t tid是实际上是一个地址,其指向的是线程数据的起始位置

线程局部数据存储

例如我们定义了一个全局变量g_val,将其用__thread修饰,那么每个进程都会拥有其副本,这样的称为线程的局部数据

#include<cstdio>
#include<unistd.h>
#include<pthread.h>
#include<vector>
using namespace std;
// void* task(void* arg){
//     const char* buffer = static_cast<const char*>(arg);
//     while(true){
//         printf("%s\n",buffer);
//         sleep(1);
//     }
//     return nullptr;
// }// int main(){
// #define NUM 10
//     pthread_t array[NUM] ={0};
//     for(int i = 0 ; i < NUM;i++ ){
//         char buffer[1024];
//         snprintf(buffer,sizeof buffer,"thread: %d",i);
//         pthread_t tid = 0;
//         pthread_create(&tid,nullptr,task,buffer);
//         array[i] = tid;
//     }//     for(int i = 0 ; i < NUM; i++){
//         pthread_join(array[i],nullptr);
//     }//     return 0;
// }
//上面的代码是错误的,会导致每个线程都是从9开始访问,因为其传的是地址,而每次for都会更改地址指向内容,而且线程进入的速度不同,导致异常情况__thread int g_val = 10;void* task(void* arg){// const char* buffer = static_cast<const char*>(arg);// int cnt = 10;// while (cnt--)// {//     printf("%s\n",buffer);//     sleep(1);// }printf("%x\n",&g_val);return 0;
}
struct thread{pthread_t tid;char buffer[1024];
};
int main(){printf("%x\n",&g_val);
#define NUM 10vector<thread*> v(NUM);for(int i = 0 ; i < NUM;i++ ){v[i] = new thread;snprintf(v[i]->buffer,sizeof v[i]->buffer,"thread :%d",i);pthread_t tid = 0;pthread_create(&tid,nullptr,task,(void*)v[i]->buffer);//rintf("%x\n",tid);v[i]->tid = tid;}for(int i = 0 ; i < NUM; i++){pthread_join(v[i]->tid,nullptr);//printf("on sucess:%x\n",v[i]->tid);delete v[i];}return 0;
}

我们观察到每个线程的g_val的地址都不同。 

6.线程与进程

进程是承担分配资源的基本实体,线程是进程中的执行流,是CPU调度的基本单位。

信号的作用实体是进程,会让每个PCB中的信号pending位改变,因此线程推出时并不会涉及到信号,因为当线程异常时,如果有信号,那么会杀死整个进程。

http://www.dtcms.com/wzjs/54551.html

相关文章:

  • 在线流程图网站怎么做开发网站建设
  • 北京医疗机构网站前置审批需要的材料有哪些注册百度账号
  • 做婚庆的网站产品推销
  • 做订单管理网站用什么软件百度竞价点击一次多少钱
  • 有专门做消除网站上对公司不利的新站seo优化快速上排名
  • 猎头公司猎头大连seo优化
  • 国外设计模板网站媒体135网站
  • 做网站模板的海报尺寸多少上海关键词优化外包
  • php开发大型网站开发seo站内优化教程
  • 广州网络推广服务商百度竞价优化软件
  • 关于图书网站建设的书籍在线培训平台有哪些
  • 佛山疫情最新动态seo排名诊断
  • dede网站主页打不开网络营销的seo是做什么的
  • 大连b2c网站建设搜狗推广效果好吗
  • 深圳 手机网站建设杭州网站优化多少钱
  • 龙岗区网站建设公司搭建网站
  • 简述网站规划的主要任务成都网站搜索排名优化公司
  • 网站建设公司推广广告语百度竞价推广属于什么广告
  • 嘉兴 网站制作百度知道灰色词代发收录
  • 卡密网站怎么做怎样通过网络销售自己的产品
  • 网站开发基础知识企业员工培训课程
  • iis网站权限配置营销计划
  • 社区网站如何做许昌seo推广
  • 长春比较有名的做网站建设销售渠道
  • 合肥专业商业网站杭州百度百家号seo优化排名
  • 做佩戴护身符的厂家网站广东做seo的公司
  • 东莞住房和建设局网站超级外链在线发布
  • 备案需要网站吗昆明seo培训
  • 那个网站做外贸seo优化公司
  • 培训网站欣赏关键词优化的软件