Linux多线程

多线程的引入原因:
1、进程间切换开销大。
2、进程间通信麻烦而且效率低(因为每个进程在操作系统中都独立的存在于自己的虚拟地址空间中,认为自己独享4G内存。进程为了安全起见,相互隔离是必要的,但进程间的通信需求也是客观的。)
3、线程技术保留了进程技术实现多任务的特性。线程是一种轻量级进程。一个进程中可以有多个线程。
4、线程的改进就是在线程间切换和线程间通信上提升了效率(多线程若处于同一进程中,类似于同一进程的多个函数,相互间访问更方便高效)。
5、多线程在多核心CPU(对称多处理器架构SMP)架构下效率最大化。
6、现代操作系统的最小调度单位是线程,最小资源分配单位是进程。

线程常见函数:
1、线程创建函数
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
参数1:创建的线程
参数2:线程的属性,一般为NULL
参数3:线程绑定的函数
参数4:函数的参数
2、线程退出函数
void pthread_exit(void *retval);
参数:保存线程退出以后的返回值,一般为NULL
3、线程回收函数
int pthread_join(pthread_t thread, void **retval);
参数1:要回收的线程
参数2:存储被等待线程的返回值,一般为NULL

线程同步三种机制:信号量、互斥锁、条件变量

信号量:
Linux sem信号量是一种特殊的变量,访问具有原子性,用于解决进程或线程间共享资源引发的同步问题。用户态线程对sem信号量可以有两种操作:等待信号量、发送信号量。通过对信号量的控制,从而实现共享资源的顺序访问。
信号量的创建就像声明一般的变量一样简单,例如sem_t sem;之后对该信号量进行初始化和使用。
一个线程执行等待信号量函数时会阻塞住等待被另一个线程发信号量唤醒。
初始化函数:
int sem_init(sem_t *sem, int pshared, unsigned int value);
参数1:信号量
参数2:为0表示线程,大于0表示进程
参数3:设置信号量的初始值,一般设为0
阻塞等待信号量函数
int sem_wait(sem_t *sem);
参数:等待的信号量
发送信号量函数:
int sem_post(sem_t *sem);
参数:要发送的信号量
回收信号量函数
int sem_destroy(sem_t *sem);
参数:要回收的信号量
信号量代码示例
任务:用户从终端输入任意字符然后统计个数显示,输入end则结束。
使用多线程实现:主线程获取用户输入并判断是否退出,子线程计数
在这里插入图片描述

在这里插入图片描述

互斥锁:
互斥锁又称互斥量,可以认为是一种特殊信号量,信号量可以有多种,互斥锁只有是一种。
互斥锁的作用就是用来做关键段的保护。锁住关键段,防止别的线程插入进来,打断本段代码的执行。哪个线程抢到锁就执行哪个线程,释放锁后所有的线程都有机会去抢锁。
初始化函数
int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
参数1:互斥锁
参数2:互斥锁的属性,一般为NULL
上锁函数
int pthread_mutex_lock(pthread_mutex_t *mutex);
参数:互斥锁
解锁函数
int pthread_mutex_unlock(pthread_mutex_t *mutex);
参数:互斥锁
回收互斥锁函数
int pthread_mutex_destroy(pthread_mutex_t *mutex);
参数:互斥锁
互斥锁代码示例
任务:用户从终端输入任意字符然后统计个数显示,输入end则结束。
使用多线程实现:主线程获取用户输入并判断是否退出,子线程计数
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
条件变量
条件变量是线程所特有的,也是线程同步效率最高的一种机制。
与互斥锁不同,条件变量是用来等待而不是上锁的。条件变量用来自动阻塞一个线程,直到某特殊情况发生为止。通常条件变量和互斥锁同时使用。条件变量使我们可以睡眠等待某种条件出现。条件变量是利用线程间共享的全局变量进行同步一种机制,主要包括两个动作:一个线程等待“条件变量的条件成立”而挂起;另一个线程使“条件成立”(发出条件成立信号)。
条件的检测是在互斥锁的保护下进行的。如果一个条件为假,一个线程自动阻塞,并释放等待状态改变的互斥锁。如果另一个线程改变条件,它发信号给关联条件变量,唤醒一个或多个等待它的线程,被唤醒的线程重新获得互斥锁,重新评价条件。如果两进程共享可读写的内存,条件变量可以被用来实现这两进程间的线程同步。
条件变量分为两部分:条件和变量。条件本身是由互斥锁保护,线程在改变条件状态之前先要上锁。它是利用线程间共享的全局变量进行同步一种机制。
初始化函数
int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
参数1:条件变量
参数2:条件变量的属性,一般为NULL
阻塞等待条件变量函数
int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
参数1:条件变量
参数2:互斥锁
广播唤醒方式函数
int pthread_cond_broadcast(pthread_cond_t *cond);
参数:条件变量
单播唤醒方式函数
int pthread_cond_signal(pthread_cond_t *cond);
参数:条件变量
回收条件变量函数
int pthread_cond_destroy(pthread_cond_t *cond);
参数:条件变量
条件变量代码示例
任务:用户从终端输入任意字符然后统计个数显示,输入end则结束。
使用多线程实现:主线程获取用户输入并判断是否退出,子线程计数
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值