博客推荐:
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. 线程同步
    使用条件变量,一个线程等待,当满足某个条件时,由另外一个线程唤醒。

标签: 进程, linux, 线程, pthread, 多线程, 编程, mutex, 加锁, 互斥

相关文章推荐

添加新评论,含*的栏目为必填