1. 死锁与解锁:
复制代码
#include 
#include 
#include 
using namespace std;
//thread引用类型函数,模板,避免类型转换,尽量指针,引用
//锁住一个变量之后,尽快操作完解锁,不要再锁,否则互锁
#define COUNT 100000
mutex g_mutex1, g_mutex2;//互斥量
void add1(int *p1, int *p2)
{
    for (int i = 0; i < COUNT; i++)
    {
        /*g_mutex1.lock();
        p1++;
        g_mutex2.lock();
        p2++;
        g_mutex1.unlock();
        g_mutex2.unlock();*/
        g_mutex1.lock();
        (*p1)++;
        g_mutex1.unlock();
        
        g_mutex2.lock();
        (*p2)++;
        g_mutex2.unlock();
    }
}
void add2(int *p1, int *p2)
{
    for (int i = 0; i < COUNT; i++)
    {
        /*g_mutex2.lock();
        g_mutex1.lock();
        p1++;
        g_mutex1.unlock();
        p2++;
        g_mutex2.unlock();*/
        g_mutex2.lock();
        (*p2)++;
        g_mutex2.unlock();
        g_mutex1.lock();
        (*p1)++;
        g_mutex1.unlock();
    }
}
void main()
{
    int a = 0;
    int b = 0;
    thread th1(add1, &a, &b);
    thread th2(add2, &a, &b);
    th1.join();
    th2.join();
    while (1)
    {
        cout << a << endl;
        cout << b << endl;
        this_thread::sleep_for(chrono::seconds(1));
    }
    cin.get();
}
复制代码
 2. 迅雷面试题:
  编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,
  要求输出结果必须按ABC的顺序显示。如:ABCABC...,依次递推。
    【参考答案】
复制代码
//编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,
//要求输出结果必须按ABC的顺序显示。如:ABCABC...,依次递推。
#include 
#include 
#include 
#include 
using namespace std;
int LOOP = 10;    //循环次数
int flag = 0;    //标识符 012012012012
mutex m;
condition_variable cv;
void fun(int id)
{
    for (int i = 0; i < LOOP; i++)
    {
        unique_lock ulk(m);        //设定锁定
        while ((id-65) != flag)
        {
            cv.wait(ulk);                //不是该出现的场合,就等待
        }
        cout << (char)id;                //转换id
        flag = (flag + 1) % 3;            //012,012,012,...
        cv.notify_all();                //通知全部
    }
}
void main()
{
    thread t1(fun, 65);
    thread t2(fun, 66);
    thread t3(fun, 67);
    t1.join();
    t2.join();
    t3.join();
    cin.get();
}
复制代码
    运行结果:
    【分析】若题目变为:4个线程,输出结果要求为: ABCDABCDABCD...又该如何做呢?
复制代码
//编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,
//要求输出结果必须按ABC的顺序显示。如:ABCABC...,依次递推。
#include 
#include 
#include 
#include 
using namespace std;
int LOOP = 10;    //循环次数
int flag = 0;    //标识符 012012012012
mutex m;
condition_variable cv;
void fun(int id)
{
    for (int i = 0; i < LOOP; i++)
    {
        unique_lock ulk(m);        //设定锁定
        while ((id-65) != flag)
        {
            cv.wait(ulk);                //不是该出现的场合,就等待
        }
        cout << (char)id;                //转换id
        flag = (flag + 1) % 4;            //012,012,012,...
        cv.notify_all();                //通知全部
    }
}
void main()
{
    thread t1(fun, 65);
    thread t2(fun, 66);
    thread t3(fun, 67);
    thread t4(fun, 68);
    t1.join();
    t2.join();
    t3.join();
    t4.join();
    cin.get();
}
复制代码
    运行结果:
 3. 思考:上题中若变为开启5个线程,ID分别为1,2,3,4,5,每个线程将自己的ID在屏幕上打印10遍,要求输出结果为:12345,54321,12345,54321,...依此类推。
 
 
4. 线程交换 swap:
复制代码
#include 
#include 
using namespace std;
void main()
{
    thread t1([]() {cout << "ZhangShan"<
#include 
#include 
using namespace std;
void main()
{
    thread t1([]() 
    {
        int i = 0;
        while (1)
        {
            i++;
            if (i > 1000000000)
            {
                break;
            }
        }
        cout << i << endl;
        system("pause");
    });
    
    cout << "t1:" << t1.get_id() << endl;    //6872
    //t1.join();
    thread t2 = move(t1);//线程移动,t2具备了t1的属性,t1挂了
    cout << "t1:" << t1.get_id() << endl;    //0
    cout << "t2:" << t2.get_id() << endl;    //6872
    t2.join();
    cin.get();
}
复制代码
    运行结果:
 6. 线程自动加解锁:
复制代码
#include 
#include 
#include 
using namespace std;
#define N 10000000
mutex g_mutex;//全局互斥量
void add(int *p)
{
    for (int i = 0; i < N; i++)
    {
        unique_lock ulk(g_mutex);
        //没有mutex所有权,自动加锁自动解锁,根据块语句锁定
        //根据mutex属性来决定,是否可以加锁
        //lock_guard lgd(g_mutex);    
        //拥有mutex所有权,自动加锁自动解锁
        //读取mutex失败的情况下就会一直等待
        (*p)++;
    }
}
void main()
{
    int a = 0;
    thread t1(add, &a);
    thread t2(add, &a);
    t1.join();
    t2.join();
    cout << a << endl;
    cin.get();
}
复制代码
7. 线程等待固定时间:
复制代码
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
condition_variable cv;
mutex m;
bool done=false;
void run()
{
    auto start = chrono::high_resolution_clock::now();    //当前时间
    auto end = start + chrono::seconds(3);
    unique_lock ulk(m);
    while (!done)
    {
        if (cv.wait_until(ulk, end) == cv_status::timeout)//超时
        {
            done = true;
            break;
        }
    }
    //this_thread::sleep_until(end);
    system("pause");
}
void main1601()
{
    thread th(run);
    cin.get();
}
void main()
{
    time_t t1, t2;
    auto start = chrono::high_resolution_clock::now();    //当前时间
    t1 = time(&t1);
    double db = 0;
    for (int i = 0; i < 1000000000; i++)
    {
        db += i;
    }
    auto end = chrono::high_resolution_clock::now();    //当前时间
    t2 = time(&t2);
    cout << (end - start).count() << endl;    //10^-9秒(ns)
    cout << difftime(t2, t1) << endl;
    cin.get();
}
复制代码
 8. 多线程实现生产者、消费者:
复制代码
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
mutex m;
condition_variable isfull, isempty;//处理两种情况
bool flag = true;//标志,消费完了就退出
vector myint(10);//开辟10个元素
void produce(int num)    //生产
{
    for (int i = 0; i < num; i++)
    {
        unique_lock lk(m);    //锁定
        while (myint.size()>=10)
        {
            isempty.wait(lk);    //满了一直等待
        }
        myint.push_back(i);//插入
        cout << "生产" << i << endl;
        isfull.notify_all();//通知消费者
    }
    this_thread::sleep_for(chrono::seconds(5));//休眠5秒
    flag = false;
}
void consume()    //消费
{
    while (flag)
    {
        unique_lock lk(m);    //锁定
        while (myint.size()==0)
        {
            isfull.wait(lk);//等待
        }
        
        if (flag)
        {
            cout << "消费" << myint[myint.size() - 1] << " " << this_thread::get_id() << endl;
            myint.pop_back();//剔除最后一个
            isempty.notify_all();//通知生产者继续生产
        }
    }
}
void main()
{
    thread t1(consume);    //消费者
    thread t2(consume);
    thread t3(consume);
    //produce(100);
    thread s1(produce,15);//消费者
    thread s2(produce,15);
    t1.join();
    t2.join();
    t3.join();
    cin.get();
}https://www.cnblogs.com/si-lei/p/9515012.html