线程是进程内的一条执行路径

线程是操作系统能够进行调度的最小执行单元

线程特点:

①轻量级:

        线程的创建和销毁开销远小于进程,线程的切换版本低(无需切换进程地址空间)

②资源共享

         同一进程内的线程共享全局变量,堆内存,文件描述符,线程间通信简单(可访问共享内存)

③独立执行流

           每个线程拥有自己独立的程序计数器,栈,寄存器集合

④并发执行

            多线程在多核CPU上会实现真正的并行执行,单核CPU上通过时间分片实现并发

线程创建函数

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

thread:创建的线程ID

attr:线程属性(NULL表示使用默认属性)

start_rountine:线程入口函数(新线程开始执行的函数)

arg:传递给线程入口的参数

成功返回0,新线程开始执行start_rountine函数;失败返回非0错误码。

关键特性:

①并发执行,新线程和创建它的线程(主线程)并发运行,具体调度顺序由操作系统决定

②资源共享(共享内存,堆,文件描述符)

③独立的栈空间(局部变量)

int pthread_join(pthread_t thread,  void**retval)

pthread_join()等待thread指定的线程退出,线程未退出时,该方法阻塞。

retval:接受thread线程退出时,指定的退出信息

int pthread_exit(void*retval)

pthread_exit()退出线程

retval:指定推出信息

POSIX 信号量初始化函数 sem_init()

        是 Linux/Unix 系统里用来初始化信号量的系统调用,主要用于线程 / 进程间的同步与互斥。

sem_init()

sem:指向sem_t指针,表示存储信号量

pshared:决定信号量的共享范围

                0:表示仅在当前进程中的线程之间共享

                非0值:表述在多个进程间进行共享(需放在共享内存区域)

value:信号量的初值,资源数量

信号量本质上是一个计数器,用来实现:

  1. 互斥:多个线程 / 进程竞争同一资源时,保证同一时间只有一个访问(比如初始值为 1)
  2. 同步:控制线程 / 进程的执行顺序(比如生产者 - 消费者模型)

原子操作,让信号量减1

原子操作,让信号量加1

销毁创建的信号量,释放所有与该信号量相关的资源

线程同步

          线程同步指的是当一个线程在对某个临界资源进行操作时,其他线程都不可以对这个资
源进行操作,直到该线程完成操作,其他线程才能操作,也就是协同步调,让线程按预定的
先后次序进行运行。线程同步的方法有四种:互斥锁、信号量、条件变量、读写锁。

互斥锁的初始化

pthread_mutex_init()

mutex:指向mutex_t的指针,表示哪个互斥锁

attr:表示互斥锁的属性

        NULL:默认属性

int pthread_mutex_lock(pthread_mutex_t * mutex)     表示对某个互斥锁上锁

int pthread_mutex_unlock(pthread_mutex_t *mutex)  表示对某个互斥锁解锁
注意事项:
1.加锁解锁必须成对出现,否则容易导致死锁
2.避免重复加锁
3.尽量保证锁的范围小,保证程序的并发性能


int pthread_mutex_destroy(pthread_mutex_t *mutex)  互斥锁的销毁

线程和进程之间的区别:

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐