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

linux学习笔记-读《Linux编程技术详解》(12)-Linux系统下的多线程

线程,也被称为轻量进程,指的是进程中某个单一顺序的控制流。线程是进程中的实体,一个进程可以拥有多个线程,而一个线程必须有一个父进程。线程与父进程的其他线程一起共享进程的所有资源。线程本身不拥有系统资源

线程,也被称为轻量进程,指的是进程中某个单一顺序的控制流。线程是进程中的实体,一个进程可以拥有多个线程,而一个线程必须有一个父进程。线程与父进程的其他线程一起共享进程的所有资源。线程本身不拥有系统资源,只是拥有一些运行必须的数据结构而已。进程是资源管理的最小单位,而线程是程序执行的最小单位。

根据线程的调度者是位于系统内核中还是位于系统内核外,线程可以划分为内核态线程和用户态线程两大类。

1.         内核态线程

该线程由内核调度程序直接调度,在核心态下可以充分发挥多处理机的优势。目前,Linux系统的标准线程库就是采用内核线程方式实现多线程。内核线程可以充分发挥多处理器的性能。

2.         用户态线程

一个进程可以包含几个线程。这些线程从内核调度程序的视角来看只是一个进程,内核将他们作为一个进程来调度。线程之间的调度是在用户态下进行的。实际上,线程对于内核调度程序而言是不可见的。用户线程的优点是调度的高效性;缺点是在多处理器上性能不高,一个线程的系统调用阻塞将导致整个线程组阻塞。

目前,线程主要的实现方法是用户态线程。与内核态线程不同,用户态线程在线程切换时不需要调用系统调用。因此,资源消耗较少,有利于实现一个进程启动多个线程的场合。同时,通过修改用户态线程的实现方式可以适应特殊应用的要求,这对于多媒体实时处理尤为有利。

有资料表明,进程在系统资源方面的开销是线程的30倍左右。因此,在资源消耗上,进程与线程相比,没有任何的优势。

Linux系统中,所有与线程相关的函数都是以pthread开头的. pthread_create函数用于在当前进程中加入新的线程。

int pthread_create(pthread_t *restrict thread,

                             const pthread_attr_t *restrict attr,

                             void *(*start_routine)(void *), void *restrict arg);

UNIX不同,在Linux中,当调用pthread_create创建线程时,系统首先创建一个新的进程,再在该进程内创建需要的线程。

pthread_exit函数用于结束线程的运行。

           void pthread_exit(void *value_ptr);

为了让主线程等待创建的线程运行完成后才退出,可在main函数中调用pthread_join函数。

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

pthread_join函数将挂起调用该函数的线程,直到thread参数指定的线程运行结束。

 

线程属性

           int pthread_attr_init(pthread_attr_t *attr);

pthread_attr_init 函数用于使用参数attr中的属性来初始化线程属性对象。该函数必须在pthread_create函数之前调用。

线程的分离状态将决定线程如何结束。默认情况下,创建出的线程是处于非分离状态的,这种线程在进程没有退出之前,不会释放线程所占用的资源。非分离线程可以通过调用pthread_join函数来等待其他线程结束。这样线程在结束之后会释放自己占用的资源。处于分离状态的线程会在线程退出时释放所占用的资源。

 

           int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);

此函数设置线程属性对象的线程分离状态。

 

           int pthread_attr_getdetachstate(const pthread_attr_t *attr,

                                                int *detachstate);

此函数从attr参数中获得线程分离状态信息。

 

           int pthread_attr_setscope(pthread_attr_t *attr, int contentionscope);

           int pthread_attr_getscope(const pthread_attr_t *attr,

                                                int *restrict contentionscope);

这两个函数用于设置或获得线程属性对象的作用域。作用域用于控制线程是在进程内还是在系统所有进程间进行调度。

 

线程同步

多进程对共享资源进行访问的时候,必须保证某个时刻只有一个进程访问资源,这个问题在多线程情况下,同样是存在的。为此,Linux系统提供了互斥锁来保证某个时刻只有一个线程使用资源。

互斥锁提供了在多线程情况下相互排斥的方法。

互斥锁

互斥锁的锁定和解锁是通过pthread_mutex_lock函数和pthread_mutex_unlock函数来实现的。互斥锁一般用来保护数据结构。通过线程对互斥锁的锁定和解锁,能够实现某一时刻只有一个线程访问数据结构。

互斥锁操作主要有三种行为,分别是加锁、解锁和测试加锁。当对互斥锁进行了加锁操作,在没有进行解锁之前,任何线程都没有办法获得互斥锁。

创建互斥锁可通过两种途径来实现:

1、 通过POSIX标准中定义的宏来实现对互斥锁的初始化,

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

2、 调用pthread_mutex_init函数实现互斥锁的初始化,

int pthread_mutex_init(pthread_mutex_t *restrict mutex,

                               const pthread_mutexattr_t *restrict attr);

使用PTHREAD_MUTEX_INITIALIZER宏来初始化互斥锁,其效果等同于调用pthread_mutex_init函数时将attr参数指定为NULL

 

pthread_mutex_lock函数用于对互斥锁进行加锁操作:

           int pthread_mutex_lock(pthread_mutex_t *mutex)

phtread_mutex_trylock函数与pthread_mutex_lock函数功能类似 ,同样用于实现对互斥锁的加锁操作。

           int pthread_mutex_trylock(pthread_mutex_t *mutex);

具体不同参考man manual;

           int pthread_mutex_unlock(pthread_mutex_t *mutex);

此函数将释放参数mutex中指向的互斥锁,释放类型依赖于互斥锁的锁类型。


推荐阅读
  • 第七课主要内容:多进程多线程FIFO,LIFO,优先队列线程局部变量进程与线程的选择线程池异步IO概念及twisted案例股票数据抓取 ... [详细]
  • 深入理解Java虚拟机的并发编程与性能优化
    本文主要介绍了Java内存模型与线程的相关概念,探讨了并发编程在服务端应用中的重要性。同时,介绍了Java语言和虚拟机提供的工具,帮助开发人员处理并发方面的问题,提高程序的并发能力和性能优化。文章指出,充分利用计算机处理器的能力和协调线程之间的并发操作是提高服务端程序性能的关键。 ... [详细]
  • 预备知识可参考我整理的博客Windows编程之线程:https:www.cnblogs.comZhuSenlinp16662075.htmlWindows编程之线程同步:https ... [详细]
  • linux进阶50——无锁CAS
    1.概念比较并交换(compareandswap,CAS),是原⼦操作的⼀种,可⽤于在多线程编程中实现不被打断的数据交换操作࿰ ... [详细]
  • 本文介绍了操作系统的定义和功能,包括操作系统的本质、用户界面以及系统调用的分类。同时还介绍了进程和线程的区别,包括进程和线程的定义和作用。 ... [详细]
  • HashMap的相关问题及其底层数据结构和操作流程
    本文介绍了关于HashMap的相关问题,包括其底层数据结构、JDK1.7和JDK1.8的差异、红黑树的使用、扩容和树化的条件、退化为链表的情况、索引的计算方法、hashcode和hash()方法的作用、数组容量的选择、Put方法的流程以及并发问题下的操作。文章还提到了扩容死链和数据错乱的问题,并探讨了key的设计要求。对于对Java面试中的HashMap问题感兴趣的读者,本文将为您提供一些有用的技术和经验。 ... [详细]
  • 1Lock与ReadWriteLock1.1LockpublicinterfaceLock{voidlock();voidlockInterruptibl ... [详细]
  • 从批量eml文件中提取附件的Python代码实现方法
    本文介绍了使用Python代码从批量eml文件中提取附件的实现方法,包括获取eml附件信息、递归文件夹下所有文件、创建目的文件夹等步骤。通过该方法可以方便地提取eml文件中的附件,并保存到指定的文件夹中。 ... [详细]
  • Java编程思想一书中第21章并发中关于线程间协作的一节中有个关于汽车打蜡与抛光的小例子(原书的704页)。这个例子主要展示的是两个线程如何通过wait ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 基于Socket的多个客户端之间的聊天功能实现方法
    本文介绍了基于Socket的多个客户端之间实现聊天功能的方法,包括服务器端的实现和客户端的实现。服务器端通过每个用户的输出流向特定用户发送消息,而客户端通过输入流接收消息。同时,还介绍了相关的实体类和Socket的基本概念。 ... [详细]
  • 如何用JNI技术调用Java接口以及提高Java性能的详解
    本文介绍了如何使用JNI技术调用Java接口,并详细解析了如何通过JNI技术提高Java的性能。同时还讨论了JNI调用Java的private方法、Java开发中使用JNI技术的情况以及使用Java的JNI技术调用C++时的运行效率问题。文章还介绍了JNIEnv类型的使用方法,包括创建Java对象、调用Java对象的方法、获取Java对象的属性等操作。 ... [详细]
  • 本文介绍了使用readlink命令获取文件的完整路径的简单方法,并提供了一个示例命令来打印文件的完整路径。共有28种解决方案可供选择。 ... [详细]
author-avatar
小菜一蝶2502902341
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有