posix thread(Chromium中Thread的创建)

:暂无数据 2026-07-09 03:30:01 :0

posix thread(Chromium中Thread的创建)

本篇文章给大家谈谈posix thread,以及Chromium中Thread的创建对应的知识点,文章可能有点长,但是希望大家可以阅读完,增长自己的知识,最重要的是希望对各位有所帮助,可以解决了您的问题,不要忘了收藏本站喔。

本文目录

Chromium中Thread的创建

在chromium中如何创建线程

创建线程对象后,可以调用Start,或者StartWithOptions指定创建线程的一些选项。

Thread的构造函数里创建了一个id_event,和start_event的WaitableEvent对象,同时把name赋值给name_变量。

调用Start会创建一个默认Option,调用StartWithOptions.

StartWithOptions中做了两件事,1.调用MessageLoop::CreateUnbound,2.调用PlatformThread::CreateWithPriority。

1.创建MessageLoop

MessageLoop::CreateUnbound静态函数,创建一个MessageLoop,MessageLoop中含有一个IncomingTaskQueue,MessageLoopTaskRunner。

2.调用PlatformThread::CreateWithPriority

这部分是由各个平台各自实现的, Posix平台的实现如下

调用posix平台的pthread_create创建一个线程,然后调用ThreadFunc

delegate为Thread, 会在线程中调用Thread::ThreadMain,退出这个方法后会调用base::TerminateOnThread()

ThreadMain中会调用MessageLoop的bindToCurrentThread

其中会创建MessageLoopPump,IncomingTaskQueue::StartScheduing, TaskRunner::BindToCurrentThread。

ThreadMain中还会调用Run(RunLoop* run_loop)

delegate为MessageLoop,RunLoop::Run调用MessageLoop::Run

最后会调用MessageLoopPump的Run方法, MessageLoopPump根据MessageLoop的不同type会创建不同的子类,默认是MessagePumpDefault。

MessageLoopPump的作用就是启动一个消息循环,然后去schedule delegate去做一些work。delegate是MessageLoop

ios 几种多线程 区别

1 Thread
2 Cocoa operations
3 Grand Central Dispatch (GCD)
Thread 轻量级 最复杂 你需要自己管理thread的生命周期,线程之间的同步。线程共享同一应用程序的部分内存空间,它们拥有对数据相同的访问权限。你得协调多个线程对同一数据的访问,一般做法是在访问之前加锁,这会导致一定的性能开销。在 iOS 中我们可以使用多种形式的 thread:
Cocoa threads: 使用NSThread 或直接从 NSObject 的类方法 performSelectorInBackground:withObject: 来创建一个线程。如果你选择thread来实现多线程,那么 NSThread 就是官方推荐优先选用的方式。
POSIX threads: 基于 C 语言的一个多线程库,
Cocoa operations是基于 Obective-C实现的,类 NSOperation 以面向对象的方式封装了用户需要执行的操作,我们只要聚焦于我们需要做的事情,而不必太操心线程的管理,同步等事情,因为NSOperation已经为我们封装了这些事情。 NSOperation 是一个抽象基类,我们必须使用它的子类。iOS 提供了两种默认实现:NSInvocationOperation 和 NSBlockOperation。
Grand Central Dispatch (GCD): iOS4 才开始支持,它提供了一些新的特性,以及运行库来支持多核并行编程,它的关注点更高:如何在多个 cpu 上提升效率。

有关POSIX协议

POSIX是Portable Operating System Interface of Unix的缩写。由IEEE(Institute of Electrical and Electronic Engineering)开发,由ANSI和ISO标准化。
posix - POSIX标准
1003.0
管理 POSIX 开放式系统环境(OSE)。IEEE 在 1995 年通过了这项标准。 ISO 的版本是 ISO/IEC 14252:1996。
1003.1
被广泛接受、用于源代码级别的可移植性标准。1003.1 提供一个操作系统的 C 语言应用编程接口(API)。IEEE 和 ISO 已经在 1990 年通过了这个标准,IEEE 在 1995 年重新修订了该标准。
1003.1b
一个用于实时编程的标准(以前的 P1003.4 或 POSIX.4)。这个标准在 1993 年被 IEEE 通过,被合并进 ISO/IEC 9945-1。
1003.1c
一个用于线程(在一个程序中当前被执行的代码段)的标准。以前是 P1993.4 或 POSIX.4 的一部分,这个标准已经在 1995 年被 IEEE 通过,归入 ISO/IEC 9945-1:1996。
1003.1g
一个关于协议独立接口的标准,该接口可以使一个应用程序通过网络与另一个应用程序通讯。 1996 年,IEEE 通过了这个标准。
1003.2
一个应用于 shell 和 工具软件的标准,它们分别是操作系统所必须提供的命令处理器和工具程序。 1992 年 IEEE 通过了这个标准。ISO 也已经通过了这个标准(ISO/IEC 9945-2:1993)。
1003.2d
改进的 1003.2 标准。
1003.5
一个相当于 1003.1 的 Ada 语言的 API。在 1992 年,IEEE 通过了这个标准。并在 1997 年对其进行了修订。ISO 也通过了该标准。
1003.5b
一个相当于 1003.1b(实时扩展)的 Ada 语言的 API。IEEE 和 ISO 都已经通过了这个标准。ISO 的标准是 ISO/IEC 14519:1999。
1003.5c
一个相当于 1003.1q(协议独立接口)的 Ada 语言的 API。在 1998 年, IEEE 通过了这个标准。ISO 也通过了这个标准。
1003.9
一个相当于 1003.1 的 FORTRAN 语言的 API。在 1992 年,IEEE 通过了这个标准,并于 1997 年对其再次确认。ISO 也已经通过了这个标准。
1003.10
一个应用于超级计算应用环境框架(Application Environment Profile,AEP)的标准。在 1995 年,IEEE 通过了这个标准。
1003.13
一个关于应用环境框架的标准,主要针对使用 POSIX 接口的实时应用程序。在 1998 年,IEEE 通过了这个标准。
1003.22
一个针对 POSIX 的关于安全性框架的指南。
1003.23
一个针对用户组织的指南,主要是为了指导用户开发和使用支持操作需求的开放式系统环境(OSE)框架
2003
针对指定和使用是否符合 POSIX 标准的测试方法,有关其定义、一般需求和指导方针的一个标准。在 1997 年,IEEE 通过了这个标准。
2003.1
这个标准规定了针对 1003.1 的 POSIX 测试方法的提供商要提供的一些条件。在 1992 年,IEEE 通过了这个标准
2003.2
一个定义了被用来检查与 IEEE 1003.2(shell 和 工具 API)是否符合的测试方法的标准。在 1996 年,IEEE 通过了这个标准。
除了 1003 和 2003 家族以外,还有几个其它的 IEEE 标准,例如 1224 和 1228,它们也提供开发可移植应用程序的 API。
本段 回目录 posix - 程序示例下面是一个 POSIX 线程的简单示例程序:
#include #include #include void *thread_function(void *arg) { int i; for ( i=0; i《20; i ) { printf("Thread says hi!\n"); sleep(1); } return NULL; } int main(void) { pthread_t mythread; if ( pthread_create( &mythread, NULL, thread_function, NULL) ) { printf("error creating thread."); abort(); } if ( pthread_join ( mythread, NULL ) ) { printf("error joining thread."); abort(); } exit(0); }
要编译这个程序,只需先将程序存为 thread1.c,然后输入:$ gcc thread1.c -o thread1 -lpthread

posix多线程是用户级还是内核级

1.内核级线程:
(1)线程的创建、撤销和切换等,都需要内核直接实现,即内核了解每一个作为可调度实体的线程。
(2)这些线程可以在全系统内进行资源的竞争。
(3)内核空间内为每一个内核支持线程设置了一个线程控制块(TCB),内核根据该控制块,感知线程的存在,并进行控制。
在一定程度上类似于进程,只是创建、调度的开销要比进程小。有的统计是1:10
2.用户级线程:
(1)用户级线程仅存在于用户空间。——》对比内核(3)
(2)内核并不能看到用户线程。——》重要的区别
(3)内核资源的分配仍然是按照进程进行分配的;各个用户线程只能在进程内进行资源竞争。

posix线程调度是一个混合模型,很灵活,足以在标准的特定实现中支持用户级和内核级的线程。模型中包括两级调度--线程及和内核实体级。线程级与用户级线程类似,内核实体由内核调度。由线程库来决定它需要多少内核实体,以及他们是如何映射的。
POSIX 引入了一个线程调度竞争范围(thread-scheduling contention scope)的概念,这个. 概念赋予了程序员一些控制权,使它们可以控制怎样将内核实体映射为线程。线程的contentionscope属性可是PTHREAD_SCOPE_PROCESS,也可以是PTHREAD_SCOPE_SYSTEM。带有PTHREAD_SCOPE_PROCESS属性的线程与它所在的进程中的其他线程竞争处理器资源。带有PTHREAD_SCOPE_SYSTEM属性的线程很像内核级线程,他们在全系统的范围内竞争处理器资源。POSIX的一种映射方式将PTHREAD_SCOPE_SYSTEM线程和内核实体之间绑定起来。
内核级线程创建时先设置线程属性PTHREAD_SCOPE_SYSTEM,代码如下,:
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); //设置内核级的线程,以获取较高的响应速度
//创建线程
ret = pthread_create(&iAcceptThreadId, &attr, AcceptThread, NULL);

pthread_once的pthread_once

POSIX的只执行一次的pthread_once#ifdefWIN32#include《windows.h》#defineSLEEP(ms)Sleep(ms)#elseifdefined(LINUX)#include《stdio.h》#defineSLEEP(ms)sleep(ms)#endif#include《cassert》#include《pthread.h》//取出线程的IDintGetThreadID(){#ifdefWIN32return(int)pthread_getw32threadhandle_np(pthread_self());#elseifdefined(LINUX)return(int)pthread_self();#endif}//该静态变量被所有线程使用staticints_nThreadResult=0;staticpthread_once_tonce=PTHREAD_ONCE_INIT;//该初始化函数,我在多线程下只想执行一次voidthread_init(){s_nThreadResult=-1;printf(){pthread_ttid1,tid2;pthread_create(&tid1,NULL,&theThread,NULL);pthread_create(&tid2,NULL,&theThread,NULL);//无论是否休眠,两个子线程最终都会被主线程join到//因为两个子线程都是默认的PTHREAD_CREATE_JOINABLE类型//SLEEP(3);void*status=NULL;intrc=pthread_join(tid1,&status);assert(rc==0&&pthread_join1,rc);if(status!=PTHREAD_CANCELED&&status!=NULL){printf(Returnedvaluefromthread:%d\n,*(int*)status);}rc=pthread_join(tid2,&status);assert(rc==0&&pthread_join2,rc);if(status!=PTHREAD_CANCELED&&status!=NULL){printf(Returnedvaluefromthread:%d\n,*(int*)status);}return0;}

Linux POSIX编程如何查询指定的线程是否阻塞

使用线程间通信,在才确定的代码位置使用mutex就可以完成你所要的功能。
线程互斥
  互斥意味着“排它”,即两个线程不能同时进入被互斥保护的代码。Linux下可以通过pthread_mutex_t 定义互斥体机制完成多线程的互斥操作,该机制的作用是对某个需要互斥的部分,在进入时先得到互斥体,如果没有得到互斥体,表明互斥部分被其它线程拥有,此时欲获取互斥体的线程阻塞,直到拥有该互斥体的线程完成互斥部分的操作为止。
  下面的代码实现了对共享全局变量x 用互斥体mutex 进行保护的目的:
int x; // 进程中的全局变量
pthread_mutex_t mutex;
pthread_mutex_init(&mutex, NULL); //按缺省的属性初始化互斥体变量mutex
pthread_mutex_lock(&mutex); // 给互斥体变量加锁
… //对变量x 的操作
phtread_mutex_unlock(&mutex); // 给互斥体变量解除锁
  线程同步
  同步就是线程等待某个事件的发生。只有当等待的事件发生线程才继续执行,否则线程挂起并放弃处理器。当多个线程协作时,相互作用的任务必须在一定的条件下同步。
  Linux下的C语言编程有多种线程同步机制,最典型的是条件变量(condition variable)。pthread_cond_init用来创建一个条件变量,其函数原型为:
pthread_cond_init (pthread_cond_t *cond, const pthread_condattr_t *attr);
  pthread_cond_wait和pthread_cond_timedwait用来等待条件变量被设置,值得注意的是这两个等待调用需要一个已经上锁的互斥体mutex,这是为了防止在真正进入等待状态之前别的线程有可能设置该条件变量而产生竞争。pthread_cond_wait的函数原型为:
pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex);
  pthread_cond_broadcast用于设置条件变量,即使得事件发生,这样等待该事件的线程将不再阻塞:
pthread_cond_broadcast (pthread_cond_t *cond) ;
  pthread_cond_signal则用于解除某一个等待线程的阻塞状态:
pthread_cond_signal (pthread_cond_t *cond) ;
  pthread_cond_destroy 则用于释放一个条件变量的资源。
  在头文件semaphore.h 中定义的信号量则完成了互斥体和条件变量的封装,按照多线程程序设计中访问控制机制,控制对资源的同步访问,提供程序设计人员更方便的调用接口。
sem_init(sem_t *sem, int pshared, unsigned int val);
  这个函数初始化一个信号量sem 的值为val,参数pshared 是共享属性控制,表明是否在进程间共享。
sem_wait(sem_t *sem);
  调用该函数时,若sem为无状态,调用线程阻塞,等待信号量sem值增加(post )成为有信号状态;若sem为有状态,调用线程顺序执行,但信号量的值减一。
sem_post(sem_t *sem);
  调用该函数,信号量sem的值增加,可以从无信号状态变为有信号状态。

线程特有数据(Thread Specific Data)

在单线程程序中,我们经常要使用 全局变量 来实现多个函数间共享数据。在多线程环境下,由于数据空间是共享的,因此全局变量也为所有线程所共有。但有时在应用程序设计中有必要提供 线程私有 的全局变量,仅在某个线程中有效,但可以跨多个函数访问,这样每个线程访问它自己独立的数据空间,而不用担心和其它线程的同步访问。

这样在一个线程内部的各个函数都能访问、但其它线程不能访问的变量,我们就需要使用 线程局部静态变量 (Static memory local to a thread) 同时也可称之为 线程特有数据 (Thread-Specific Data 或 TSD),或者 线程局部存储 (Thread-Local Storage 或 TLS)。

POSIX 线程库提供了如下 API 来管理线程特有数据(TSD):

第一参数 key 指向 pthread_key_t 的对象的指针。请 注意 这里 pthread_key_t 的对象占用的空间是用户事先分配好的, pthread_key_create 不会动态生成 pthread_key_t 对象。
第二参数 desctructor ,如果这个参数不为空,那么当每个线程结束时,系统将调用这个函数来释放绑定在这个键上的内存块。

有时我们在线程里初始化时,需要避免重复初始化。我们希望一个线程里只调用 pthread_key_create 一次,这时就要使用 pthread_once 与它配合。

第一个参数 once_control 指向一个 pthread_once_t 对象,这个对象必须是常量 PTHREAD_ONCE_INIT ,否则 pthread_once 函数会出现不可预料的结果。
第二个参数 init_routine ,是调用的初始化函数,不能有参数,不能有返回值。
如果成功则返回0,失败返回非0值。

创建完键后,必须将其与线程数据关联起来。关联后也可以获得某一键对应的线程数据。关联键和数据使用的函数为:

第一参数 key 指向键。
第二参数 value 是欲关联的数据。
函数成功则返回0,失败返回非0值。

注意: 用 pthread_setspecific 为一个键指定新的线程数据时,并不会主动调用析构函数释放之前的内存,所以调用线程必须自己释放原有的线程数据以回收内存。

获取与某一个键关联的数据使用函数的函数为:

参数 key 指向键。
如果有与此键对应的数据,则函数返回该数据,否则返回NULL。

删除一个键使用的函数为:

参数 key 为要删除的键。
成功则返回0,失败返回非0值。

注意: 该函数将键设置为可用,以供下一次调用 pthread_key_create() 使用。它并不检查当前是否有线程正在使用该键对应的线程数据,所以它并不会触发函数 pthread_key_create 中定义的 destructor 函数,也就不会释放该键关联的线程数据所占用的内存资源,而且在将 key 设置为可用后,在线程退出时也不会再调用析构函数。所以在将 key 设置为可用之前,必须要确定:

在 Linux 中每个进程有一个全局的数组 __pthread_keys ,数组中存放着 称为 key 的结构体,定义类似如下:

在 key 结构中 seq 为一个序列号,用来作为使用标志指示这个结构在数组中是否正在使用,初始化时被设为0,即表示 不在使用 。 destructor 用来存放一个析构函数指针。

pthread_create_key 会从数组中找到一个还未使用的 key 元素,将其序列号 seq 加1,并记录析构函数地址,并将 key 在数组 __pthread_keys 中的 下标 作为返回值返回。那么如何判断一个 key 正在使用呢?

如果 key 的序列号 seq 为偶数则表示未分配,分配时将 seq 加1变成奇数,即表示正在使用。这个操作过程采用原子 CAS 来完成,以保证线程安全。在 pthread_key_delete() 时也将序列号 seq 加1,表示可以再被使用,通过序列号机制来保证回收的 key 不会被复用(复用 key 可能会导致线程在退出时可能会调用错误的析构函数)。但是一直加1会导致序列号回绕,还是会复用 key ,所以调用 pthread_create_key 获取可用的 key 时会检查是否有回绕风险,如果有则创建失败。

除了进程范围内的 key 结构数组外,系统还在进程中维护关于每个线程的控制块 TCB(用于管理寄存器,线程栈等),里面有一个 pthread_key_data 类型的数组。这个数组中的元素数量和进程中的 key 数组数量相等。 pthread_key_data 的定义类似如下:

根据 pthread_key_create() 返回的可用的 key 在 __pthread_keys 数组中的下标, pthread_setspecific() 在 pthread_key_data 的数组 中定位相同下标的一个元素 pthread_key_data ,并设置其序号 seq 设置为对应的 key 的序列号,数据指针 data 指向设置线程特有数据(TSD)的值。

pthread_getspecific() 用于将 pthread_setspecific() 设置的 data 取出。

线程退出时, pthread_key_data 中的序号 seq 用于判断该 key 是否仍在使用中(即与在 __pthread_keys 中的同一个下标对应的 key 的序列号 seq 是否相同),若是则将 pthread_key_data 中 data(即 线程特有数据 TSD)作为参数调用析构函数。

由于系统在每个进程中 pthread_key_t 类型的数量是有限的,所有在进程中并不能获取无限个 pthread_key_t 类型。Linux 中可以通过 PTHREAD_KEY_MAX(定义于 limits.h 文件中)或者系统调用 sysconf(_SC_THREAD_KEYS_MAX) 来确定当前系统最多支持多少个 key 。 Linux 中默认是 1024 个 key,这对大多数程序来书已经够了。如果一个线程中有多个线程局部存储变量(TLS),通常可以将这些变量封装到一个数据结构中,然后使用封装后的数据结构和一个线程局部变量相关联,这样就能减少对键值的使用。

***隐藏网址***
***隐藏网址***
***隐藏网址***
***隐藏网址***
***隐藏网址***
***隐藏网址***
***隐藏网址***
***隐藏网址***

OK,关于posix thread和Chromium中Thread的创建的内容到此结束了,希望对大家有所帮助。

posix thread(Chromium中Thread的创建)

本文编辑:admin

更多文章:


函数的类型有哪些?函数类型有哪些

函数的类型有哪些?函数类型有哪些

本篇文章给大家谈谈函数分类,以及函数的类型有哪些对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。

2026年10月11日 20:20

源码交易平台哪个最靠谱(国内低代码平台哪家强)

源码交易平台哪个最靠谱(国内低代码平台哪家强)

本篇文章给大家谈谈源码交易平台哪个最靠谱,以及国内低代码平台哪家强对应的知识点,文章可能有点长,但是希望大家可以阅读完,增长自己的知识,最重要的是希望对各位有所帮助,可以解决了您的问题,不要忘了收藏本站喔。

2026年10月11日 20:10

gcc编译器参数(深度linux的arm-linux-gnueabihf-gcc编译参数如何配)

gcc编译器参数(深度linux的arm-linux-gnueabihf-gcc编译参数如何配)

其实gcc编译器参数的问题并不复杂,但是又很多的朋友都不太了解深度linux的arm-linux-gnueabihf-gcc编译参数如何配,因此呢,今天小编就来为大家分享gcc编译器参数的一些知识,希望可以帮助到大家,下面我们一起来看看这个

2026年10月11日 19:30

用记事本写vbs代码(怎么把记事本改成vbs格式)

用记事本写vbs代码(怎么把记事本改成vbs格式)

各位老铁们好,相信很多人对用记事本写vbs代码都不是特别的了解,因此呢,今天就来为大家分享下关于用记事本写vbs代码以及怎么把记事本改成vbs格式的问题知识,还望可以帮助大家,解决大家的一些困惑,下面一起来看看吧!

2026年10月11日 17:23

asp是什么检查项目(医院血液检验项目RPR、TPPA、HIV-Ab各是什么意思)

asp是什么检查项目(医院血液检验项目RPR、TPPA、HIV-Ab各是什么意思)

“asp是什么检查项目”相关信息最新大全有哪些,这是大家都非常关心的,接下来就一起看看asp是什么检查项目(医院血液检验项目RPR、TPPA、HIV-Ab各是什么意思)!

2026年10月11日 10:20

汇编输出指令(用汇编语言循环指令在屏幕中间输出红底白字的“hello I am 720“)

汇编输出指令(用汇编语言循环指令在屏幕中间输出红底白字的“hello I am 720“)

各位老铁们好,相信很多人对汇编输出指令都不是特别的了解,因此呢,今天就来为大家分享下关于汇编输出指令以及用汇编语言循环指令在屏幕中间输出红底白字的“hello I am 720“的问题知识,还望可以帮助大家,解决大家的一些困惑,下面一起来看

2026年10月11日 07:20

本地搭建springboot项目(使用eclipse构建springboot项目)

本地搭建springboot项目(使用eclipse构建springboot项目)

各位老铁们,大家好,今天由我来为大家分享本地搭建springboot项目,以及使用eclipse构建springboot项目的相关问题知识,希望对大家有所帮助。如果可以帮助到大家,还望关注收藏下本站,您的支持是我们最大的动力,谢谢大家了哈,

2026年10月11日 06:20

hump是什么意思?hump口语啥意思

hump是什么意思?hump口语啥意思

其实hump的问题并不复杂,但是又很多的朋友都不太了解hump是什么意思,因此呢,今天小编就来为大家分享hump的一些知识,希望可以帮助到大家,下面我们一起来看看这个问题的分析吧!

2026年10月11日 03:50

java入门神器好用吗(java 7入门经典适合初学者自学用吗)

java入门神器好用吗(java 7入门经典适合初学者自学用吗)

这篇文章给大家聊聊关于java入门神器好用吗,以及java 7入门经典适合初学者自学用吗对应的知识点,希望对各位有所帮助,不要忘了收藏本站哦。

2026年10月11日 02:40

unix文件系统采用(Unix采用树形文件系统,其中“树形文件系统”什么意思)

unix文件系统采用(Unix采用树形文件系统,其中“树形文件系统”什么意思)

大家好,如果您还对unix文件系统采用不太了解,没有关系,今天就由本站为大家分享unix文件系统采用的知识,包括Unix采用树形文件系统,其中“树形文件系统”什么意思的问题都会给大家分析到,还望可以解决大家的问题,下面我们就开始吧!

2026年10月11日 00:50

最近更新

olympics音标(there are summer olympics and winter olympics是什么意思)
2026-10-11 21:50:03 浏览:0
华硕f8笔记本硬盘(华硕F8更换硬盘)
2026-10-11 21:30:05 浏览:0
1+手机11pro(一加11pro参数)
2026-10-11 20:30:02 浏览:0
热门文章

标签列表