Linux高级系统编程-线程

2023-12-13 05:04:20

进程与线程

进程 : 系统分配资源的基本单位 , 可以简单理解为一个正在进行的程序
线程 : 操作系统调度的最小单位 , 就是一段代码的执行顺序
注意:
????????1,一个进程必须要有一个线程 , 该线程被称为主线程
????????2,一个进程可以有多个线程 , 除主线程外的其他线程都是子线程
????????3,进程被销毁时 , 其中的线程也将被销毁 .
????????4,线程是轻量级的进程( LWP light weight process ),在 Linux 环境下线程的本 质仍是进程。
????????5,进程所有线程都共享该进程的资源。
线程特点:
????????类 Unix 系统中,早期是没有 线程 概念的, 80 年代才引入,借助进程机制实现出了 线程的概念。
因此在这类系统中,进程和线程关系密切:
????????1) 线程是轻量级进程 (light-weightprocess) ,也有 PCB ,创建线程使用的底层函数和进程一样,都是 clone
????????2) 从内核里看进程和线程是一样的,都有各自不同的 PCB.
????????3) 进程可以蜕变成线程
????????4) 在 linux 下,线程最是小的执行单位;进程是最小的分配资源单位 实际上,无论是创建进程的 fork ,还是创建线程的 pthreadcreate ,底层实现都是调 用同一个内核函数 clone
????????? 如果复制对方的地址空间,那么就产出一个 进程
????????? 如果共享对方的地址空间,就产生一个 线程
????????Linux内核是不区分进程和线程的 , 只在用户层面上进行区分。所以,线程所有操作函数 pthread* 是库函数,而非系统调用

线程共享与非共享的资源

共享的:
????????1) 文件描述符表
????????2) 每种信号的处理方式
????????3) 当前工作目录
????????4) 用户 ID 和组 ID
????????5) 内存地址空间 (.text/.data/.bss/heap/ 共享库 )
非共享的:
????????1) 线程 id
????????2) 处理器现场和栈指针 ( 内核栈 )
????????3) 独立的栈空间 ( 用户空间栈 )
????????4) errno 变量
????????5) 信号屏蔽字
????????6) 调度优先级

线程的优缺点

优点:
????????提高程序并发性
????????开销小
????????数据通信、共享数据方便
缺点:
????????库函数,不稳定
????????调试、编写困难、gdb 不支持
????????对信号支持不好 优点相对突出,缺点均不是硬伤。Linux 下由于实现方法导致进程、 线程差别不是很大。

查看指定进程的线程号(LWP)

ps -Lf pid
pid: 进程号
注意:
????????由于线程库原本不是系统本身的, 所以在链接时需要手动链接库文件编译源文件时输入
????????gcc *.c -l pthread

获取当前线程号

????????线程号只在它所属的进程环境中有效。
????????线程号则用 pthread_t 数据类型来表示, Linux 使用无符号长整数表示。
所需头文件
????????#include <pthread.h>
函数
????????pthread_t pthread_self(void);
功能:
????????获取线程号。
参数:
????????无
返回值:
????????调用线程的线程 ID
#include <stdio.h>
#include <pthread.h>
int main(int argc, char const *argv[])
{
    pthread_t tid = pthread_self();
    printf("%ld\n",tid);
    return 0;
}

创建线程

所需头文件
????????#include <pthread.h>
函数
????????int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
????????????????void *(*start_routine)(void *), void *arg );
参数:
????????thread:线程标识符地址。
????????attr:线程属性结构体地址,通常设置为 NULL
????????start_routine:线程函数的入口地址。
????????arg:传给线程函数的参数。
返回值:
????????成功:0
????????失败:非 0
#include <stdio.h>
#include <pthread.h>
//注意线程调用的函数返回值为任意指针类型
void *myfunc01()
{
    printf("线程%ld正在执行\n",pthread_self());
    return NULL;
}
void *myfunc02(void *arg)
{
    printf("线程%ld正在执行,参数为:%s\n",pthread_self(),(char *)arg);
    return NULL;
}
int main(int argc, char const *argv[])
{
    pthread_t p1,p2,p3;
    pthread_create(&p1,NULL,myfunc01,NULL);
    pthread_create(&p2,NULL,myfunc02,"Thread2");
    pthread_create(&p3,NULL,myfunc02,"Thread3");
    getchar();
    return 0;
}

线程的回收

????????等待线程结束(此函数会阻塞),并回收线程资源,类似进程的 wait() 函数。如果线程已经结束,那么该函数会立即返回。
????????#include <pthread.h>

文章来源:https://blog.csdn.net/weixin_50963877/article/details/134956819
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。