热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Linux系统编程学习:009线程

背景我们在此之前完成了有关进程的学习。从这一讲开始我们学习线程。在Linux系统编程学习:有关概念中,我们介绍了线程

Linux 系统编程 学习:009-线程

背景

我们在此之前完成了 有关进程的学习。从这一讲开始我们学习线程。

在Linux 系统编程 学习:有关概念中,我们介绍了线程和进程的概念。


概念

我们知道:



  • 线程是cpu或操作系统调度的基本单位。线程大部分的资源是共享的,仅仅申请了自己的栈、空间。

  • 线程是进程内部的一个执行分支,线程量级很小。

  • 在程序中创建线程,可以提高效率,进程内线程越多,争夺到CPU的概率就越大,执行代码的概率就越大(有一个度)。

  • 线程可以解决很多问题,而不会像进程一样有那么多的开销。

  • 在线程中需要注意同步的问题。


线程开发基本步骤

#if 0
为什么要用线程
http://blog.csdn.net/huangyimo/article/details/46756151
线程比进程更快,开销更小。
1.当需要在在进程间共享数据时,我们必须使用IPC来进行通信,因为两个进程间没有“天生”的共享内存区(进程要求虚拟空间独立,如果想共享数据,必须把这几个进程的某个地址映射到相同的物理内存上)。IPC的使用将会导致开销上升。
2.需要创建新进程时,我们使用fork()函数。虽然该函数不会拷贝所有的数据,但是最基本的数据,比如页表,文件描述符表等还是需要创建的。这也会导致开销上升。
而线程完全不会有上面的问题。两个线程之间的数据共享是很自然的事,因为同一进程的线程都在一个虚拟地址空间,数据的共享就像变量赋值一样(但要注意同步问题)。线程的创建也比进程的创建快,因为它不需要复制和创建很多数据。
一个线程的bug很可能会引起该进程的崩溃(所有的线程都在同一个虚拟地址空间内,一个线程能很容易的访问到另一个线程的空间)
线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元。(调度的最小单位)
http://blog.csdn.net/suool/article/details/38542543
对于内核来说,没有线程和进程的区分(但是对于用户来说,是有区别的)
每个进程在创建的时候都申请了新的内存空间以存储代码段\数据段\BSS段\堆\栈空间,并且这些的空间的初始化值是父进程空间的,父子进程在创建后不能互访资源.
而每个新创建的线程则仅仅申请了自己的栈,空间,与同进程的其他线程共享该进程的其他数据空间包括代码段\数据段\BSS段\堆以及打开的库,mmap映射的文件与共享的空间,使得同进程下的线程共享数据十分的方便,只需借助这些共享区域即可,但也有问题即是同步问题.
线程开发的基本步骤:
#include
1. 声明以及初始化一个线程属性变量,并通过函数设置线程属性
(当不需要设置线程属性的时候,可以在后续参数的pattr部分填入NULL)
pthread_attr_t pattr; //如果不需要设置线程属性,则可以不使用这2条语句
pthread_attr_init(&pattr); //如果不需要设置线程属性,则可以不使用这2条语句
//通过函数设置线程属性
pthread_attr_getaffinity_np pthread_attr_getdetachstate
pthread_attr_getguardsize pthread_attr_getinheritsched
pthread_attr_getschedparam pthread_attr_getschedpolicy
pthread_attr_getscope pthread_attr_getstack
pthread_attr_getstackaddr pthread_attr_getstacksize
pthread_attr_setaffinity_np pthread_attr_setdetachstate
pthread_attr_setguardsize pthread_attr_setinheritsched
pthread_attr_setschedparam pthread_attr_setschedpolicy
pthread_attr_setscope pthread_attr_setstack
pthread_attr_setstackaddr pthread_attr_setstacksize
其中,用得最多是关于线程的可分离性。
// 如果一个进程是分离的,则意味着在线程结束以后,将被系统回收(常用在无反馈的线程中)
//(而不是变成僵尸来等待 pthread_join 函数的回收)
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
/*
设置线程的可分离性到属性结构体,成功返回0,失败返回errorno
pthread_attr_t : 用于赋值的属性结构体
detachstate : 设置可分离性
PTHREAD_CREATE_DETACHED 分离的。
PTHREAD_CREATE_JOINABLE 不可分离的,可汇接的(默认值)
可汇接的线程在结束时,可以使用以下方式返回值给其他线程
void pthread_exit(void *retval);
“ 多线程的进程就好比一条河流中的多条支流,支流的终点,将重新汇聚在一起。
————叔超硕徳
*/
int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate);
// 获取线程属性结构体中的可分离性
2. 以指定的线程属性#attr(不需要设置线程属性时,默认填入NULL)创建一个线程#start_routine,并传入参数#arg,成功时,赋线程ID到#thread中,返回0,失败返回error number
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
/*
pthread_t tid;
pthread_create(&tid,NULL,(void *)start_routine,NULL);
*/
3. 根据情况来决定是否等待线程的返回值,如果需要等待,以下面的方式进行
int pthread_join(pthread_t thread, void **retval);
// 阻塞等待一个线程ID为#thread的不可分离线程的结束,将其返回值传入#reval
// 成功返回0,失败返回error number
一个线程所使用的内存资源在应用pthread_join调用之前不会被重新分配,所以对于每个线程必须调用一次pthread_join函数(被分离线程除外)。
4. 可以根据情况提前取消一个线程的执行
int pthread_cancel(pthread_t thread);
5. 不再使用某个线程属性结构体时,应该进行销毁
pthread_attr_destroy(&pattr);
#endif
#include
#include
#include
void *start_routine(void *arg)
{
int count = 5;
while(count--)
{
sleep(1);
printf("int child thread arg=%s\n", (char *)arg);
}
return "world"; //pthread_exit("world");
}
int main(void)
{
pthread_t tid;
char *string = "hello";
void *retval;
pthread_attr_t pattr; // 线程属性结构体 使用前应该初始化(pthread_attr_init )
pthread_attr_init(&pattr);// 结束后应该回收资源解除初始化(pthread_attr_destroy )
pthread_attr_setdetachstate(&pattr, PTHREAD_CREATE_DETACHED);// 设置线程的可分离性

errno = pthread_create(&tid, &pattr, start_routine, string); // 创建线程start_routine,为线程传参数string
if(errno != 0)
{
fprintf(stderr, "creat thread failed:%s\n", strerror(errno));
return -1;
}
pthread_attr_destroy(&pattr);
printf("in parent thread\n");
pthread_join(tid, &retval); // 等待线程的结束,并取返回值
printf("retval = %s\n", (char *)retval);
return 0;
}


推荐阅读
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文讨论了Alink回归预测的不完善问题,指出目前主要针对Python做案例,对其他语言支持不足。同时介绍了pom.xml文件的基本结构和使用方法,以及Maven的相关知识。最后,对Alink回归预测的未来发展提出了期待。 ... [详细]
  • Windows下配置PHP5.6的方法及注意事项
    本文介绍了在Windows系统下配置PHP5.6的步骤及注意事项,包括下载PHP5.6、解压并配置IIS、添加模块映射、测试等。同时提供了一些常见问题的解决方法,如下载缺失的msvcr110.dll文件等。通过本文的指导,读者可以轻松地在Windows系统下配置PHP5.6,并解决一些常见的配置问题。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 本文讲述了作者通过点火测试男友的性格和承受能力,以考验婚姻问题。作者故意不安慰男友并再次点火,观察他的反应。这个行为是善意的玩人,旨在了解男友的性格和避免婚姻问题。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • Monkey《大话移动——Android与iOS应用测试指南》的预购信息发布啦!
    Monkey《大话移动——Android与iOS应用测试指南》的预购信息已经发布,可以在京东和当当网进行预购。感谢几位大牛给出的书评,并呼吁大家的支持。明天京东的链接也将发布。 ... [详细]
  • 如何去除Win7快捷方式的箭头
    本文介绍了如何去除Win7快捷方式的箭头的方法,通过生成一个透明的ico图标并将其命名为Empty.ico,将图标复制到windows目录下,并导入注册表,即可去除箭头。这样做可以改善默认快捷方式的外观,提升桌面整洁度。 ... [详细]
  • Metasploit攻击渗透实践
    本文介绍了Metasploit攻击渗透实践的内容和要求,包括主动攻击、针对浏览器和客户端的攻击,以及成功应用辅助模块的实践过程。其中涉及使用Hydra在不知道密码的情况下攻击metsploit2靶机获取密码,以及攻击浏览器中的tomcat服务的具体步骤。同时还讲解了爆破密码的方法和设置攻击目标主机的相关参数。 ... [详细]
author-avatar
UUUUUUUUUU8
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有