C++中的多线程

c++线程中的几种锁

  • 在代码中使用pthread,进行编译时,需要使用命令 g++ -o hello hello.c -lpthread
  • Makefile怎么写?

互斥锁

互斥锁只有两种状态,锁定非锁定

头文件:
类型:pthread_mutex_t

  • pthread_mutex_lock:加锁。如果锁已经被占有,则该线程加入一个队列中。
  • pthread_mutex_trylock:尝试加锁,如果锁已被占有,则线程不加入队列,而是返回错误。
  • pthread_mutex_unlock:释放锁

Linux c++ 多线程编程基础——互斥锁

例程

  • 5个线程互斥显示数组数字,当其中一个线程在显示时,其他线程无法显示,直接退出
#include 
#include 
#include 

// 声明并且初始化锁(互斥锁)
pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
 
int tf[5];
 
void* print(void* i)
{
    /********************************************
    * 如果改为 int flag = pthread_mutex_lock(&mut); 
    * 则为阻塞的,该线程会被加入队列等待开锁 
    ********************************************/

    /**************************************************
    * 非阻塞如果不为零说明有其他线程正在进行,即不应该执行该线程
    * 因此可以判断flag并退出该线程
    **************************************************/
    int *id = (int*)i;

    int flag = pthread_mutex_trylock(&mut);
    if (flag==0)
    {
        sleep(1);
        for (int j=0;j<5;j++)
            printf("thread %d: %d\n", *id, j);
        pthread_mutex_unlock(&mut);
    }
    else
    {
        printf("thread %d: 其他线程正在进行\n", *id);
    }
}

int main()
{
    pthread_t td[5]; // 初始化线程
    for(int i=0;i<5;i++)
        tf[i] = i;
    for(int i=0;i<5;i++)
        // 创建线程
        pthread_create(&td[i],NULL,print,(void *)&tf[i]);
    for(int i=0;i<5;i++)
    {
        // 运行线程,join函数确保子线程执行完了主程序才退出
        pthread_join(td[i],NULL);
    }
    pthread_mutex_destroy(&mut);
}

条件锁

条件锁就是所谓的条件变量,某一个线程因为某个条件为满足时可以使用条件变量使改程序处于阻塞状态。一旦条件满足以“信号量”的方式唤醒一个因为该条件而被阻塞的线程。

头文件:
类型:pthread_cond_t

  • pthread_cond_wait:线程阻塞在条件变量
  • pthread_cond_signal:线程被唤醒

linux C++ 多线程使用pthread_cond 条件变量
线程属性pthread_attr_t简介

例程

  • 线程0、线程1互斥加一个数,加一次唤醒一次条件触发的线程2,如果线程2处于阻塞等待状态则被唤醒
  • 线程2判断数值大小时,给线程0、1上锁,停止加数,当数字小于10时,等待3秒,否则加100退出该线程
  • 线程0、1各加10次退出线程,线程2检测到数字大于10加100后退出线程,三个线程都结束程序退出
#include 
#include 
#include 

#define NUM_THREADS 3 
#define TCOUNT      10 
#define COUNT_LIMIT 10 

int count = 0;
int thread_ids[3] = {0,1,2};
pthread_mutex_t count_mutex;  // 计数时上锁
pthread_cond_t  count_threshold_cv;

void *inc_count(void *idp)
{
    int i = 0;
    int taskid = 0;
    int *my_id = (int*)idp;

    for (i=0; i

自旋锁

当发生阻塞时,互斥锁可以让CPU去处理其他的任务;而自旋锁让CPU一直不断循环请求获取这个锁,它会一直占用CPU请求这个自旋锁使得CPU不能去做其他的事情,直到获取这个锁为止,比较耗费CPU

头文件:
类型:pthread_spinlock_t

  • 初始化:pthread_spin_init(pthread_spinlock_t *__lock, int __pshared);
  • pthread_spin_lock(x); //只有在获得锁的情况下才返回,否则一直“自旋”
  • pthread_spin_trylock(x); //如果该锁已经被争用,那么该函数立即返回一个非0值,而不会自旋等待锁被释放;
  • 释放锁:phtread_spin_unlock(x);
  • 释放资源:pthread_spin_destroy(&lock);

注意:自旋锁适合于短时间的的轻量级的加锁机制

代码同互斥锁,更改init、lock、unlock、destroy即可

...保持更新中

你可能感兴趣的:(C++中的多线程)