深入浅出:线程以及线程锁

目录

线程和线程锁概念

线程锁的概念

线程的特点

线程的使用

创建线程 pthread_create

回收线程pthread_join

退出线程 pthread_exit

线程锁的使用

线程同步之互斥锁(Mutex)

初始化互斥锁

获取互斥锁

释放互斥锁

销毁互斥锁

初始化条件变量

等待条件变量

发送信号

广播信号

销毁条件变量

实例:每次打印都实现翻转数组


线程和线程锁概念

线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。一个进程可以包含一个或多个线程,而每个线程都有自己的指令指针和寄存器状态,它们共享进程的资源,如内存空间、文件句柄和网络连接等。

线程锁的概念

线程锁的基本思想是,只有一个线程能持有锁,其他试图获取锁的线程将被阻塞,直到锁被释放。这样,锁就确保了在任何时刻,只有一个线程能够访问临界区(即需要保护的代码段或数据),从而保证了数据的完整性和一致性。

线程的特点

  1. 轻量级进程:相比进程,线程的创建和切换成本更低,因为它们共享相同的地址空间和资源,不需要进行系统调用和上下文切换。

  2. 并发执行:线程允许在一个进程内部并发执行多个控制流,使得程序能够同时处理多个任务,提高程序的响应速度和效率。

  3. 资源共享:线程共享进程的资源,如内存、文件句柄和网络连接等,这减少了资源的开销,但也要求对共享资源进行同步和保护,以防止数据竞争和不一致。

  4. 通信便捷:由于线程共享同一进程的资源,它们之间的通信比进程间通信更为简单和快速,通常只需要使用局部变量或全局变量即可。

  5. 独立调度和执行:线程可以独立于其他线程进行调度和执行,操作系统可以根据需要将CPU时间分配给不同的线程,而无需切换到不同的进程。

  6. 线程状态:线程也有自己的生命周期,包括创建、就绪、运行、阻塞和终止等状态。线程状态的变化由操作系统调度器控制。

  7. 线程同步:为了保证数据的一致性和完整性,线程在访问共享资源时需要进行同步。常用的同步机制包括互斥锁(mutex)、信号量(semaphore)、条件变量(condition variable)等。

  8. 线程间通信:虽然线程共享资源,但在某些情况下,线程之间也需要进行通信,如通知某一线程完成特定任务或传递数据。这可以通过共享内存、信号量或条件变量等方式实现。

  9. 线程优先级:线程可以有不同的优先级,高优先级的线程在调度时会得到更多的CPU时间,从而影响线程的执行顺序和进程的整体性能。

线程的使用

创建线程 pthread_create

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, 
                    void *(*start_routine) (void *), void *arg);
功能:创建线程
参数:thread:线程标识
            attr:线程属性, NULL:代表设置默认属性
            start_routine:函数名:代表线程函数
            arg:用来给前面函数传参
返回值:成功:0
              失败:错误码

回收线程pthread_join

int  pthread_join(pthread_t thread,  void **value_ptr) 
功能:用于等待一个指定的线程结束,阻塞函数
参数:thread:创建的线程对象
        value_ptr:指针*value_ptr指向线程返回的参数
返回值:成功 : 0
       失败:errno

退出线程 pthread_exit

int  pthread_exit(void *value_ptr) 
功能:用于退出线程的执行
参数:value_ptr:线程退出时返回的值(任意类型)
返回值:成功 : 0
        失败:errno

简单用线程实现一下主线程循环从终端输入,线程函数将数据循环输出,当输入quit结束程序。

线程锁的使用

线程同步之互斥锁(Mutex)

互斥锁(Mutex)是一种用于同步线程访问共享资源的机制,确保在任何时刻只有一个线程能够访问临界区,从而避免了数据竞争和不一致性问题。以下是互斥锁相关函数的详细解析:

初始化互斥锁

C

1int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
  • 功能:初始化互斥锁。
  • 参数
    • mutex:指向要初始化的互斥锁的指针。
    • attr:指向互斥锁属性结构的指针,如果为NULL,则使用默认属性。
  • 返回值:成功返回0,失败返回非零值。
获取互斥锁

C

1int pthread_mutex_lock(pthread_mutex_t *mutex);
  • 功能:尝试获取互斥锁,如果锁已经被另一个线程持有,当前线程将被阻塞,直到锁可用。
  • 参数
    • mutex:指向要获取的互斥锁的指针。
  • 返回值:成功返回0,失败返回非零值。

pthread_mutex_lockpthread_mutex_trylock的区别在于,pthread_mutex_lock是阻塞的,即如果锁被占用,调用线程会等待直至获取到锁;而pthread_mutex_trylock是非阻塞的,如果锁被占用,它会立即返回,不等待锁释放。

释放互斥锁

C

1int pthread_mutex_unlock(pthread_mutex_t *mutex);
  • 功能:释放由当前线程持有的互斥锁。
  • 参数
    • mutex:指向要释放的互斥锁的指针。
  • 返回值:成功返回0,失败返回非零值。
销毁互斥锁

C

1int pthread_mutex_destroy(pthread_mutex_t *mutex);
  • 功能:销毁互斥锁,通常在不再需要互斥锁时调用。
  • 参数
    • mutex:指向要销毁的互斥锁的指针。
  • 返回值:成功返回0,失败返回非零值。
初始化条件变量

C

1int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
  • 功能:初始化条件变量。
  • 参数
    • cond:指向要初始化的条件变量的指针。
    • attr:指向条件变量属性的指针,通常设为NULL以使用默认属性。
  • 返回值:成功返回0,失败返回非零值。
等待条件变量

C

1int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
  • 功能:线程挂起等待,直到条件变量被信号唤醒。
  • 参数
    • cond:指向要等待的条件变量的指针。
    • mutex:与条件变量关联的互斥锁,必须在调用前锁定并在返回后再次锁定。
  • 返回值:成功返回0,失败返回非零值。
  • 注释:当没有条件产生时函数会阻塞,同时会自动解锁互斥锁;一旦条件产生或接收到信号,函数结束阻塞并重新锁定互斥锁。
发送信号

C

1int pthread_cond_signal(pthread_cond_t *cond);
  • 功能:向条件变量发送信号,唤醒一个等待该条件变量的线程。
  • 参数
    • cond:指向条件变量的指针。
  • 返回值:成功返回0,失败返回非零值。
  • 注释:通常在条件满足后调用,以通知等待线程继续执行。
广播信号

C

1int pthread_cond_broadcast(pthread_cond_t *cond);
  • 功能:向条件变量广播信号,唤醒所有等待该条件变量的线程。
  • 参数
    • cond:指向条件变量的指针。
  • 返回值:成功返回0,失败返回非零值。
  • 注释:与pthread_cond_signal类似,但唤醒所有等待线程,而非仅唤醒一个。
销毁条件变量

C

1int pthread_cond_destroy(pthread_cond_t *cond);
  • 功能:销毁条件变量。
  • 参数
    • cond:指向要销毁的条件变量的指针。
  • 返回值:成功返回0,失败返回非零值。

实例:每次打印都实现翻转数组

.

注:由于线程是随机执行的,所以此时我们不得不用上互斥锁,否则就会出现一些意外情况,这与我们使用标志位是一个道理,例如flag为true的时候p1执行,为flase的p2执行,但是线程锁的逻辑更加严谨和细致一些,功能也更多一些。

  • 28
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笨笨小乌龟11

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值