一、题目要求

生产者消费者模型:在多线程下生产0~100个数,生产者线程1生产20个数据后,消费者线程1进行消费输出。

二、解答

使用到的技术:互斥锁、条件变量、多线程、双端队列

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#if 1
#include<iostream>
#include<deque>
#include<mutex>
#include<condition_variable>
using namespace std;

mutex mtx;
std::condition_variable cv;

class Queue
{
public:
//生产数据: index是生产者编号,val是生产的结果
void PushData(int index, int val)
{
unique_lock<mutex> lock(mtx);
//size == 20
cv.wait(lock, [this]()->bool {return qu.size() != 20; });
qu.push_back(val);
cv.notify_all();
cout << "Producer:" << index << " " << "val:" << val << endl;
}
//消费数据: index是消费者编号
void PopData(int index)
{
unique_lock<mutex> lock(mtx);
//!qu空 ->真 , 继续执行
cv.wait(lock, [this]()->bool {return !qu.empty(); });
int val = qu.front();
qu.pop_front();
cv.notify_all();
cout << "Customer:" << index << " " << "val:" << val << endl;
}
private:
deque<int> qu;
};
void Producer(Queue& qu, int index)
{
for (int i = 0; i < 100; ++i)
{
qu.PushData(index, i);
}
}
void Customer(Queue& qu, int index)
{
for (int i = 0; i < 100; ++i)
{
qu.PopData(index);
}
}

int main()
{
Queue qu;
thread tha(Producer, std::ref(qu), 1);
thread thb(Customer, std::ref(qu), 1);

//thread thc(Producer, std::ref(qu), 2);
//thread thd(Customer, std::ref(qu), 2);

tha.join();
thb.join();
//thc.join();
//thd.join();
return 0;
}
#endif

在这里插入图片描述

三、题目要求

实现一个循环队列,生产者线程生产0~100, 每次最多生产8个,然后消费者线程进行输出使用。

根据锁的粒度分为:

  • 行锁:并发性强,锁开销较大
  • 表锁:并发性弱,锁开销较小

    四、解答

    (1)行锁

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    #if 1
    #include<iostream>
    #define MAXSIZE 8
    #include<mutex>
    #include<condition_variable>

    using namespace std;
    template<class T>
    class Queue
    {
    public:
    Queue()
    :data(new T[MAXSIZE]), maxsize(MAXSIZE), front(0), rear(0), size(0)
    {}
    ~Queue()
    {
    if (nullptr != data)
    {
    delete data;
    }
    maxsize = -1;
    front = -1;
    rear = -1;
    size = -1;
    }
    bool Capacity()const { return maxsize; }
    bool Size()const { return size; }
    bool Empty()const { return size == 0; }
    bool Full()const { return size == maxsize; }
    bool Push_back(T& val)
    {
    if (Full()) return false;
    data[rear] = val;
    rear = (rear + 1) % maxsize;
    ++size;
    return true;
    }
    bool Pop_front(T& val)
    {
    if (Empty()) return false;
    val = data[front];
    front = (front + 1) % maxsize;
    --size;
    return true;
    }

    private:
    T* data;
    int maxsize;
    int size;
    int front;
    int rear;
    };
    Queue<int> qu;
    std::mutex mtx;
    std::condition_variable cv;
    int number = 0;
    void Producer(int index)
    {
    for (int i = number; i < 100; ++i)
    {
    //行锁
    unique_lock<mutex> lock(mtx);
    //当qu不满 为真,继续执行
    cv.wait(lock, []()->bool {return !qu.Full(); });
    //
    qu.Push_back(i);
    cv.notify_all();
    cout << "Producer:" << index <<" "<< "val:" << i << endl;
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }
    }
    void Customer(int index)
    {
    for (int i = number; i < 100; ++i)
    {
    //行锁
    unique_lock<mutex> lock(mtx);
    //当qu不空 为真,继续执行
    cv.wait(lock, []()->bool {return !qu.Empty(); });
    //
    int val = 0;
    qu.Pop_front(val);
    cv.notify_all();
    cout << "Customer:" << index << " " << "val:" << val << endl;
    }
    }
    int main()
    {
    thread tha(Producer, 1);
    thread thb(Customer, 1);
    tha.join();
    thb.join();
    return 0;
    }

    #endif
    在这里插入图片描述

(2)表锁

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#if 1
#include<iostream>
#define MAXSIZE 8
#include<mutex>
#include<condition_variable>

using namespace std;
template<class T>
class Queue
{
public:
Queue()
:data(new T[MAXSIZE]), maxsize(MAXSIZE), front(0), rear(0), size(0)
{}
~Queue()
{
if (nullptr != data)
{
delete data;
}
maxsize = -1;
front = -1;
rear = -1;
size = -1;
}
bool Capacity()const { return maxsize; }
bool Size()const { return size; }
bool Empty()const { return size == 0; }
bool Full()const { return size == maxsize; }
bool Push_back(T& val)
{
if (Full()) return false;
data[rear] = val;
rear = (rear + 1) % maxsize;
++size;
return true;
}
bool Pop_front(T& val)
{
if (Empty()) return false;
val = data[front];
front = (front + 1) % maxsize;
--size;
return true;
}

private:
T* data;
int maxsize;
int size;
int front;
int rear;
};


Queue<int> qu;
std::mutex mtx;
std::condition_variable cv;
int number = 0;
void Producer(int index)
{
unique_lock<mutex> lock(mtx);
for (int i = number; i < 100; ++i)
{
//当qu不满 为真,继续执行
cv.wait(lock, []()->bool {return !qu.Full(); });
qu.Push_back(i);
cv.notify_all();
cout << "Producer:" << index <<" "<< "val:" << i << endl;
//std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
void Customer(int index)
{
unique_lock<mutex> lock(mtx);
for (int i = number; i < 100; ++i)
{
//当qu不空 为真,继续执行
cv.wait(lock, []()->bool {return !qu.Empty(); });
int val = 0;
qu.Pop_front(val);
cv.notify_all();
cout << "Customer:" << index << " " << "val:" << val << endl;
}
}
int main()
{
thread tha(Producer, 1);
thread thb(Customer, 1);
tha.join();
thb.join();
return 0;
}

在这里插入图片描述