C++多线程编程二

2021-07-20 23:07

阅读:421

标签:cout   for   img   color   参考答案   lib   必须   mes   cst   

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 )
    {
        /*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 )
    {
        /*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  endl;
        cout  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 )
    {
        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 )
    {
        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"endl; });
    thread t2([]() {cout "LiSi"endl; });

    cout "t1.get_id():" "    t2.get_id():"  endl;

    swap(t1, t2);    //交换句柄

    cout "t1.get_id():" "    t2.get_id():"  endl;

    t1.join();
    t2.join();

    cin.get();
}

5. 线程移动 move:

#include 
#include 
#include using namespace std;

void main()
{
    thread t1([]() 
    {
        int i = 0;
        while (1)
        {
            i++;
            if (i > 1000000000)
            {
                break;
            }
        }
        cout  endl;
        system("pause");
    });
    
    cout "t1:" //6872
    //t1.join();
    thread t2 = move(t1);//线程移动,t2具备了t1的属性,t1挂了
    cout "t1:" //0
    cout "t2:" //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 )
    {
        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  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 //10^-9秒(ns)
    cout  endl;

    cin.get();
}

 

C++多线程编程二

标签:cout   for   img   color   参考答案   lib   必须   mes   cst   

原文地址:https://www.cnblogs.com/si-lei/p/9515012.html


评论


亲,登录后才可以留言!