并发专题(二) 有关线程

有关线程

线程是进程中的一条流程。从资源组合角度来看:进程把一组相关资源组合起来,构成了一个资源平台(环境),包括地址空间(代码段,数据段),打开的文件等各类资源。从运行角度来看,代码在这个资源平台上执行的一个流程称为线程。
在这里插入图片描述

线程模型的优缺点

  • 优点
    • 一个进程可以存在多个线程(同时存在)。
    • 各个线程之间可以并发地执行。
    • 各个线程之间可以共享地址空间和文件资源。
  • 缺点
    • 一个线程的崩溃,有可能导致其所属进程的所有线程崩溃。

进程是资源分配的单位,线程是CPU调度的单位。进程拥有一个完整的资源平台,而线程只独享必不可少的资源,入寄存器和栈。同时线程具有与进程类似的五种状态,但是线程比较轻量能够减少并发时间和开销,线程的轻量级主要体现在如下方面:

  1. 线程的创建时间很短。
  2. 线程的终止时间很短。
  3. 同一进程内线程的切换时间很迅速。
  4. 同一进程内不同线程之间共享内存和文件等系统资源。

用户线程和内核线程

  1. 用户线程:用户线程是操作系统无法感知的线程,它不是由操作系统创建、调度、管理。不依赖于操作系统内核,它由一组用户级别的库函数完成,通过用户线程可以在不支持多线程模型的操作系统之上完成多线程编程。同时,用户线程的切换无须经过操作系统内核,所以它的切换会很快,同时用户还可以自己DIY线程的调度算法。但是用户态线程也有缺点,如果用户线程发起一个阻塞的系统的调用,那么它会阻塞整个进程内的所有用户线程。同时操作系统将时间片分给了进程,而没有直接分给线程,所以平均每个线程的执行时间会比较短,因此用户态线程执行起来会比较慢。
  2. 内核线程:操作系统内核中实现一种机制(线程机制),由操作系统负责创建、调度、管理线程,使用者仅需发出线程创建相关的系统调用即可。但是内核线程的创建会经历用户态到内核态的转变,所以开销比用户线程大,但是内核线程由操作系统管理,因此当其中一个线程发生阻塞时,并不会影响到同进程内其他线程的工作,同时内核线程分得的CPU时间较多,执行效率较高。
    C语言环境进程创建代码
#include <stdio.h>
#include <pthread.h>

/* 线程任务函数 */
void *mythread(void *args) {
    printf("%s\n", (char*) args);
    return NULL;
}
int main() {
    pthread_attr_t p1Attr; /* 线程的属性 */
    pthread_t p1; /* 线程 */
    int rc;
    pthread_attr_init(&p1Attr); /* 初始化线程属性 */
    pthread_attr_setscope(&p1Attr, PTHREAD_SCOPE_SYSTEM); /*与操作系统绑定*/
    pthread_attr_setschedpolicy(&p1Attr, SCHED_RR); /* 轮询的方式进行调度 */

    puts("Hello world\n");
    rc = pthread_create(&p1, &p1Attr, mythread, "A"); 
    puts("Start a new thread\n");
    rc = pthread_join(p1, NULL); 
    return 0;
}

pthread是POSIX Threads的简称。

POSIX,可移植操作系统接口(英文:Portable Operating System Interface)POSIX是IEEEE为要在各种UNIX操作系统上运行软件,而定义的一系列操作系统API接口,正式名称为IEEEE Std 1003,国际标准化组织名称

ISO/IEC 9945。 目前Linux基本上逐步实现了POSIX的兼容,但并未获得正式的POSIX认证。微软的Windows NT声称实现了部分POSIX标准。当前POSIX主要分为四部分:Base Definition、System Interfaces、Shell and Utillities、Rationale。

在Linux环境中,你可以使用<pthread.h>结合libpthread.so来创建线程,在Windows下可以使用MinGW结合pthread来创建线程,当然也可以使用<windows.h>中的windows API来创建线程,只不过<pthread.h>显得更加标准和易使用,但需要平台和工具的支持。

如你所见,线程的创建有点类似于函数的调用,然而,并不是首先执行函数然后返回给调用者,而是为调用的例程创建一个新的执行线程,它可以独立于调用者运行,至于函数什么时候被调用完全取决于操作系统(相应库函数的调度策略)。开玩笑的说:如果一个程序员遇到了一个问题,他想要用多线程去解决,那么他将面临两个问题。

那么使用多线程并发会带来哪些问题呢?

猜你喜欢

转载自blog.csdn.net/hbn13343302533/article/details/106862350
今日推荐