linux系统编程之多线程

23 篇文章 0 订阅

博客推荐:
https://blog.csdn.net/tiandc/article/details/81489308
https://www.cnblogs.com/xiehongfeng100/p/4620852.html#autoid-0-0-0
https://www.cnblogs.com/luoxn28/p/6087649.html

线程概念

线程是操作系统执行的最小单位,进程是程序运行的实例,在一个进程中至少有一个线程,一个线程只能属于一个进程。假如假如cpu是一个工厂的话,进程就相当于车间,线程就相当于车间中的工人。

“进程——资源分配的最小单位,线程——程序执行的最小单位”

同一个进程中的线程共享地址空间,共享全局变量,静态变量等,不共享局部变量等。

线程相对于进程的优势:

  1. 进程耗费的资源大,一个多进程的程序,需要创建多个进程,需要有多个地址空间,而分配地址空间的操作无疑是耗费资源比较大的,而多线程程序因为共享同一块地址空间,创建的时候不需要分配地址空间,所以耗费的资源比较少。
  2. 多个进程之间的通信只能通过IPC(进程间通信:管道,消息队列,共享内存,信号,信号量)来实现,而线程之间通信因为共享同一片地址空间的原因,通信方便。

进程相对于线程的优势:
3. 多进程程序比多线程程序健壮,每个进程都有自己的独立的地址空间,由于保护模式的存在,进程退出对于其他进程没有影响,而多线程程序其他进程的运行要依托于控制线程(主线程:当主进程创建线程之后就退化成线程),当主线程退出时,其他线程就会被强行关闭。

线程API

在这里插入图片描述

线程还有其他锁(读写锁,自旋锁),可见上方推荐博文。

线程API:

原型:

// 创建线程
#include <pthread.h>
int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
// 返回:若成功返回0,否则返回错误编号

//销毁线程
#include <pthread.h>
int pthread_exit(void *rval_ptr);

// 等待线程
#include <pthread.h>
int pthread_join(pthread_t thread, void **rval_ptr);
// 返回:若成功返回0,否则返回错误编号

//  脱离线程
#include <pthread.h>
int pthread_detach(pthread_t thread);
// 返回:若成功返回0,否则返回错误编号

// 获取线程号
#include <pthread.h>
pthread_t pthread_self(void);
// 返回:调用线程的ID

// 比较线程
#include <pthread.h>
int pthread_equal(pthread_t tid1, pthread_t tid2);
// 返回:若相等则返回非0值,否则返回0
线程互斥锁(mutex)API:

原型:

#include <pthread.h>
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);
int pthread_mutex_destroy(pthread_mutex_t *mutex);
    // 两个函数返回值,成功返回0,否则返回错误码

#include <pthread.h>
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);

pthread_mutex_init用于初始化互斥锁,mutexattr用于指定互斥锁的属性,若为NULL,则表示默认属性。除了用这个函数初始化互斥所外,还可以用如下方式初始化:pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER。
  pthread_mutex_destroy用于销毁互斥锁,以释放占用的内核资源,销毁一个已经加锁的互斥锁将导致不可预期的后果。

pthread_mutex_lock以原子操作给一个互斥锁加锁。如果目标互斥锁已经被加锁,则pthread_mutex_lock则被阻塞,直到该互斥锁占有者把它给解锁。
  pthread_mutex_trylock和pthread_mutex_lock类似,不过它始终立即返回,而不论被操作的互斥锁是否加锁,是pthread_mutex_lock的非阻塞版本。当目标互斥锁未被加锁时,pthread_mutex_trylock进行加锁操作;否则将返回EBUSY错误码。注意:这里讨论的pthread_mutex_lock和pthread_mutex_trylock是针对普通锁而言的,对于其他类型的锁,这两个加锁函数会有不同的行为。
  pthread_mutex_unlock以原子操作方式给一个互斥锁进行解锁操作。如果此时有其他线程正在等待这个互斥锁,则这些线程中的一个将获得它。

互斥锁进入死锁情况:

精彩博文: https://blog.csdn.net/ls5718/article/details/51896159

  1. 由于互斥锁(两个,一个一般不会)使用不当,例如有AB锁,AB线程都要对AB锁加锁,A线程加锁了其中A锁之后CPU被B线程抢占,B线程又对B锁进行了加锁,此时再执行下一步对A锁进行加锁时就进行不下去了 ,AB线程各对一个锁进行了加锁,导致两个线程都卡在了拿锁的操作
// 代码示例
A线程   :
		pthread_mutex_lock(mutexa); // 对A锁进行加锁
		sleep(1); // 让出时间片 ,使线程B抢占cpu
		pthread_mutex_lock(mutexb);// 对B锁进行加锁
B线程   :
		pthread_mutex_lock(mutexb); // 对B锁进行加锁
		sleep(1); // 让出时间片 ,使线程A抢占cpu
		pthread_mutex_lock(mutexa);// 对A锁进行加锁

__ FUNCTION __ 指代函数名

解决死锁方式:

精彩博文: https://blog.csdn.net/fapengcheng1996/article/details/80172078

  1. 线程同步
    使用条件变量,一个线程等待,当满足某个条件时,由另外一个线程唤醒。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值