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

做ppt选小图案的网站全球疫情最新数据消息

做ppt选小图案的网站,全球疫情最新数据消息,深圳住房建设部网站,廊坊网站小姐私做[Linux]多线程(二)原生线程库—pthread库的使用 水墨不写bug 文章目录 一、pthread原生线程库的使用1. pthread_create全面的看待线程返回值2. pthread_join3. pthread_exit对比理解线程退出?1、return退出2、调用C库函数exit()退出3、调用pt…

[Linux]多线程(二)原生线程库—pthread库的使用
@水墨不写bug


在这里插入图片描述


文章目录

  • 一、pthread原生线程库的使用
    • 1. pthread_create
    • 全面的看待线程返回值
    • 2. pthread_join
    • 3. pthread_exit
    • 对比理解线程退出?
      • 1、return退出
      • 2、调用C库函数exit()退出
      • 3、调用pthread库函数pthread_exit()退出
      • 4、被pthread_cancel取消
    • 理解线程分离?
    • 4. pthread_detach
    • 5. 互斥锁(Mutex)函数
      • pthread_mutex_init
      • pthread_mutex_lock / pthread_mutex_unlock
      • pthread_mutex_destroy
    • 6. 条件变量(Condition Variable)函数
      • pthread_cond_init
      • pthread_cond_wait
      • pthread_cond_signal / pthread_cond_broadcast
    • 7. 线程属性函数
      • pthread_attr_init / pthread_attr_destroy
      • 设置分离状态
    • 其他函数
    • C++11的线程库是对pthread原生线程库的封装


一、pthread原生线程库的使用

1. pthread_create

作用:创建新线程。
函数原型

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine)(void *), void *arg);

参数

  • thread:输出型参数,存储新线程的标识符(pthread_t类型)。
  • attr:线程属性(如栈大小、分离状态),若为NULL则使用默认属性。
  • start_routine:线程入口函数,必须为void* (*)(void*)类型。
  • arg:传递给入口函数的参数(void*类型);

全面的看待线程返回值

传递进来的参数并不一定是一个,也可以是一个ThreadData类,提前在这个类中设置好要使用的参数,那么我们就可以给新线程传递多个参数,甚至方法了!!把这个类当做一个用于线程传参的辅助类。
以及新线程执行的函数的返回值也可以是一个类:ThreadResult,把这个类看做是用于传递返回值的辅助类。 在主线程创建一个ThreadResult* 的对象tr,(void* *)&tr 即可获取返回值。
此外,主线程的传递给新线程的参数最好是堆区创建的变量:
如果是栈区的变量,创建第二个线程如果还用这个变量,也会对第一个新线程产生影响
如果是堆区的变量,那么传递给新线程之后,就相当于把这个堆区指针交给新线程维护了

返回值

  • 成功返回0,失败返回错误码(非errno,需用strerror转换)。

注意事项

  • 线程创建后立即执行,需同步共享数据。
  • 确保传递的arg指针在子线程中有效(避免悬垂指针)。
  • 默认创建的线程是“可连接的”(需要pthread_join回收资源)。

如何创建多线程?
通过循环,但是要注意,需要每次都从堆区新申请空间,而不能使用栈区空间:
例子一:
在这里插入图片描述
例子二:
在这里插入图片描述


2. pthread_join

一旦我们通过pthread_create创建了一个线程,这个线程与主线程谁先执行是不确定的(因为线程复用的进程的调度算法,父子进程谁先执行是不确定的),但是一般我们希望主线程最后退出,因为主线程需要回收新线程的资源;如果给新线程安排的任务没有完成主线程就退出了,那么新线程也一并退出(这种情况不可能出现,因为新线程的任务必须要完成)。新线程需要主线程调用pthread_join回收。

作用:等待线程终止,并回收其资源。
函数原型

int pthread_join(pthread_t thread, void **retval); 

参数

  • thread:目标线程的标识符。
  • retval:输出参数,接收线程的返回值(若为NULL则忽略返回值)。
    retval是二级指针的原因是新线程的返回值是void* 类型的指针,如果想要通过传参获取这个返回值,就需要void* 的地址,也就是void**。

返回值

  • 成功返回0,失败返回错误码。

注意事项

  • 只能对非分离(joinable)线程调用,否则返回EINVAL
  • 调用这个函数调用线程会阻塞,直到目标线程终止。
  • 必须调用pthread_joinpthread_detach避免资源泄漏,否则会出现类似于僵尸进程的线程数据结构未被释放。

3. pthread_exit

作用:终止当前线程,并传递返回值。
函数原型

void pthread_exit(void *retval); 

参数

  • retval:线程的返回值(可为NULL)。

注意事项

  • 主线程调用pthread_exit不会终止进程,其他线程继续运行。
  • 若线程未分离,返回值需由其他线程通过pthread_join获取。
  • 不要在线程中返回指向局部变量的指针(栈内存会被销毁回收)。

对比理解线程退出?

在了解线程之前,我们知道的进程退出的方法有:1、return 2、exit()。
但是在有了线程的概念之后,我们需要读线程进行更加细致的区分。以及对于线程退出,pthread库提供了多个方法。

1、return退出

主线程return就是进程结束;新线程return代表这个线程退出,返回的就是void* 类型的指针。

2、调用C库函数exit()退出

主线程和新线程都一样,只要调用eixt函数,代表整个进程退出。

3、调用pthread库函数pthread_exit()退出

对于新线程而言,调用pthread_exit就相当于return,并且pthread_eixt参数也和return的返回值相同,也是void* 指针。
对于主线程而言,调用pthread_exit函数,如果新线程没有退出,则阻塞等待新线程退出;如果新线程已经退出,则直接退出。

4、被pthread_cancel取消

int pthread_cancel(pthread_t thread);

一般通过主线程取消其他线程(用其他线程取消主线程,主线程退出,其他线程一并退出,这个结果是未定义的)。如果一个线程被取消了,那么这个线程的返回值是-1,这代表什么意思?
在pthread库中,定义了PTHREAD_CANCELED宏:

#define PTHREAD_CANCELED ((void*)-1)

这个宏标识了被取消的线程是通过pthread_cancel取消结束的。
在这里插入图片描述
运行结果:
在这里插入图片描述


理解线程分离?

如果一个线程不想被主线程回收,可以调用pthread_detach(pthead_self())或者主线程调用pthread_detach(新线程tid)。调用之后,这个线程还是属于进程内部,但是主线程可以专注于做自己的事情,而不再需要回收新线程。新线程调用之后,执行完之后直接退出并回收资源。
而一个分离的线程如果出错,OS仍然是向进程发送信号,让整个进程退出。

4. pthread_detach

作用:将线程标记为分离状态,线程终止后自动释放资源。
函数原型

int pthread_detach(pthread_t thread); 

参数

  • thread:目标线程的标识符。

返回值

  • 成功返回0,失败返回错误码。

注意事项

  • 分离线程无法再被pthread_join
  • 可在线程内部调用pthread_detach(pthread_self())自我分离。

5. 互斥锁(Mutex)函数

作用:保护共享资源,防止竞态条件。

pthread_mutex_init

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr); 
  • 初始化互斥锁,attr为属性(NULL表示默认)。

pthread_mutex_lock / pthread_mutex_unlock

int pthread_mutex_unlock(pthread_mutex_t *mutex); 
  • 加锁(阻塞)和解锁。

pthread_mutex_destroy

int pthread_mutex_destroy(pthread_mutex_t *mutex); 
  • 销毁互斥锁,释放资源。

注意事项

  • 静态初始化可用PTHREAD_MUTEX_INITIALIZER
  • 确保每次加锁后解锁,避免死锁。
  • 锁的持有时间应尽量短,减少性能影响。

6. 条件变量(Condition Variable)函数

作用:线程间通知机制,需与互斥锁配合使用。

pthread_cond_init

int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr); 
  • 初始化条件变量。

pthread_cond_wait

int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); 
  • 释放mutex并等待条件变量,被唤醒后重新获得锁。

pthread_cond_signal / pthread_cond_broadcast

int pthread_cond_signal(pthread_cond_t *cond);  // 唤醒至少一个线程 int
pthread_cond_broadcast(pthread_cond_t *cond); // 唤醒所有线程 

注意事项

  • 使用循环检查条件,防止虚假唤醒。
  • 调用pthread_cond_wait前必须持有mutex

7. 线程属性函数

作用:设置线程属性(如分离状态、栈大小)。

pthread_attr_init / pthread_attr_destroy

int pthread_attr_destroy(pthread_attr_t *attr); 
  • 初始化和销毁属性对象。

设置分离状态

pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 
  • 创建线程时直接设置为分离状态。

其他函数

  • pthread_self():获取当前线程ID。
  • pthread_equal(t1, t2):比较线程ID是否相等。

C++11的线程库是对pthread原生线程库的封装

在不同的语言中,可能会有不同的线程库,在Linux下,不同线程库都是对原生线程库的封装。而C++也不例外,在C++11引入的thread库是对pthread库的封装。


完~
转载请注明出处
在这里插入图片描述

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

相关文章:

  • 专业的网站建设企业网站推广内容
  • 建筑人网站手机怎么做网站
  • wordpress注册无效南京seo排名优化
  • 网站交易截图可以做证据吗情感营销
  • 河北沧州网站建设seo优化专员工作内容
  • 镇江企业做网站谷歌搜索网页版入口
  • 五常网站搜索引擎营销的优缺点
  • 公司网站做百度推广需要交费吗关键词在线听
  • 网站域名费会计分录怎么做个人博客网站怎么做
  • 网站建设种类 优帮云加强服务保障满足群众急需m
  • 做视频的网站靠什么收入免费seo优化工具
  • 聊城wap网站制作软文营销怎么做
  • 无忧网站建设哪家好百度客服在哪里找
  • 路由下做网站映射网络营销的主要推广方式
  • 高端网站建设哪家好南京网页搜索排名提升
  • 学做淘宝客网站有哪些海外广告投放公司
  • 门户网站栏目维护建设方案网站排名靠前
  • wordpress最简洁主题win10优化大师怎么样
  • 牛人网站建设广告推广赚钱
  • 广州宝盈网络科技有限公司网站优化设计五年级下册数学答案
  • 濮阳网站建设在哪里软文自助发布平台系统
  • 想做网站该怎么操作今日十大热点新闻头条
  • 免费代码网站可复制seo对网站优化
  • 做简单最网站的软件是免费建站的网站
  • 南宁品牌网站建设什么是全网营销推广
  • 诛仙3官方网站时竹任务荧灵怎么做石家庄seo外包的公司
  • 网站等级保护如何做廊坊关键词排名优化
  • 网站免费正能量小说百度指数官网入口
  • 专业做辅助的网站软文代写多少钱一篇
  • 唐山做网站seo网站培训班