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

从哪看出网站的建站公司希爱力双效片用后感受

从哪看出网站的建站公司,希爱力双效片用后感受,外贸网站b2c,wordpress右下角设置线程不是一个完全由内核实现的机制,它是由内核态和用户态合作完成的。pthread_create 不是一个系统调用,是 Glibc 库的一个函数,所以我们还要去 Glibc 里面去找线索。 首先处理的是线程的属性参数。例如前面写程序的时候,我们设置…

线程不是一个完全由内核实现的机制,它是由内核态和用户态合作完成的。pthread_create 不是一个系统调用,是 Glibc 库的一个函数,所以我们还要去 Glibc 里面去找线索。

首先处理的是线程的属性参数。例如前面写程序的时候,我们设置的线程栈大小。如果没有传入线程属性,就取默认值。

const struct pthread_attr *iattr = (struct pthread_attr *) attr;
struct pthread_attr default_attr;
if (iattr == NULL)
{......iattr = &default_attr;
}

接下来,就像在内核里一样,每一个进程或者线程都有一个 task_struct 结构,在用户态也有一个用于维护线程的结构,就是这个 pthread 结构。

struct pthread *pd = NULL;

凡是涉及函数的调用,都要使用到栈。每个线程也有自己的栈。那接下来就是创建线程栈了。

int err = ALLOCATE_STACK (iattr, &pd);

ALLOCATE_STACK 是一个宏,我们找到它的定义之后,发现它其实就是一个函数。allocate_stack 主要做了以下这些事情:

  • 如果你在线程属性里面设置过栈的大小,需要你把设置的值拿出来;
  • 为了防止栈的访问越界,在栈的末尾会有一块空间 guardsize,一旦访问到这里就错误了;
  • 其实线程栈是在进程的堆里面创建的。如果一个进程不断地创建和删除线程,我们不可能不断地去申请和清除线程栈使用的内存块,这样就需要有一个缓存。get_cached_stack 就是根据计算出来的 size 大小,看一看已经有的缓存中,有没有已经能够满足条件的;
  • 如果缓存里面没有,就需要调用 __mmap 创建一块新的,系统调用那一节我们讲过,如果要在堆里面 malloc 一块内存,比较大的话,用 __mmap;
  • 线程栈也是自顶向下生长的,还记得每个线程要有一个 pthread 结构,这个结构也是放在栈的空间里面的。在栈底的位置,其实是地址最高位;
  • 计算出 guard 内存的位置,调用 setup_stack_prot 设置这块内存的是受保护的;
  • 接下来,开始填充 pthread 这个结构里面的成员变量 stackblock、stackblock_size、guardsize、specific。这里的 specific 是用于存放 Thread Specific Data 的,也即属于线程的全局变量;
  • 将这个线程栈放到 stack_used 链表中,其实管理线程栈总共有两个链表,一个是 stack_used,也就是这个栈正被使用;另一个是 stack_cache,就是上面说的,一旦线程结束,先缓存起来,不释放,等有其他的线程创建的时候,给其他的线程用。

真正创建线程的是调用 create_thread 函数,这个函数定义如下:

static int
create_thread (struct pthread *pd, const struct pthread_attr *attr,
bool *stopped_start, STACK_VARIABLES_PARMS, bool *thread_ran)
{const int clone_flags = (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SYSVSEM | CLONE_SIGHAND | CLONE_THREAD | CLONE_SETTLS | CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID | 0);ARCH_CLONE (&start_thread, STACK_VARIABLES_ARGS, clone_flags, pd, &pd->tid, tp, &pd->tid);/* It's started now, so if we fail below, we'll have to cancel it
and let it clean itself up.  */*thread_ran = true;
}

如果在进程的主线程里面调用其他系统调用,当前用户态的栈是指向整个进程的栈,栈顶指针也是指向进程的栈,指令指针也是指向进程的主线程的代码。此时此刻执行到这里,调用 clone 的时候,用户态的栈、栈顶指针、指令指针和其他系统调用一样,都是指向主线程的。

但是对于线程来说,这些都要变。因为我们希望当 clone 这个系统调用成功的时候,除了内核里面有这个线程对应的 task_struct,当系统调用返回到用户态的时候,用户态的栈应该是线程的栈,栈顶指针应该指向线程的栈,指令指针应该指向线程将要执行的那个函数。

创建进程的话,调用的系统调用是 fork,在 copy_process 函数里面,会将五大结构 files_struct、fs_struct、sighand_struct、signal_struct、mm_struct 都复制一遍,从此父进程和子进程各用各的数据结构。而创建线程的话,调用的是系统调用 clone,在 copy_process 函数里面, 五大结构仅仅是引用计数加一,也即线程共享进程的数据结构。

此文章为10月Day30学习笔记,内容来源于极客时间《趣谈Linux操作系统》,推荐该课程。

http://www.ds6.com.cn/news/111050.html

相关文章:

  • 青岛商务学校网站建设广州百度seo 网站推广
  • 企业电商网站模板seo最新
  • wordpress 汽车租赁怎么优化一个网站
  • 长沙关键词优化推荐谷歌seo外包公司哪家好
  • 做淘宝客网站用什么系统有免费做网站的吗
  • 企业网络营销企业网站建设章节习题宁波seo排名优化培训
  • 浙江最近爆发的传染病广州百度seo
  • 做视频网站怎么备案临沂今日头条新闻最新
  • 男女做那个视频网站免费自拍每日一则新闻摘抄
  • 平面设计接单平台哪个靠谱点莆田seo
  • 上海的外贸网站建设公司最新战争新闻事件今天
  • 如何建立网站建设seo团队管理系统
  • 中国建设银行门户网站企业百度关键字优化
  • 河北廊坊seo网站建设网站优化东莞网站推广方案
  • 长治做网站公司2022国内外重大新闻事件10条
  • 后台风格网站百度官方网站
  • 萝岗网站建设竞价培训课程
  • 零食销售网站开发与设计长春网站开发公司
  • 山东高端网站建设方案百度移动端关键词优化
  • 建设造价信息网站点点站长工具
  • 宁蒗县政府门户网站建设吴江seo网站优化软件
  • java开源cms商品标题seo是什么意思
  • 网站认证是什么意思营销活动方案模板
  • 网站想建设子站24小时自助下单平台网站便宜
  • 个人兼职做建设网站网络营销的六大功能
  • 郑州建站模板源码软件开发公司简介
  • 哈尔滨网站制作专业百度指数十年
  • b2b网站建设排名大数据营销是什么
  • 如何用java做网站视频百度推广怎么才能效果好
  • 网站建设哪里好点郑州品牌网站建设