当前位置:网站首页>[Autumn Recruitment] [Updating ing] Hand Tear Code Series

[Autumn Recruitment] [Updating ing] Hand Tear Code Series

2022-08-10 23:11:00 20 to continue to work hard!

This year is too difficult~

Record the tearing code

clionAdd thread library link

find_package(Threads REQUIRED)
target_link_libraries(pro_con Threads::Threads)

线程池

生产者消费者

两个线程
a common buffer
Mutexes and condition variables are used to synchronize threads

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <unistd.h>


using namespace std;


// 全局变量
static const int buffsize = 10; // 缓冲区大小
static const int proNum= 20;

// 共享资源
struct resource{
    
    // 缓冲区
    int buffer[buffsize];
    // 读写指针
    size_t readPos;
    size_t writePos;
    // 锁
    std::mutex mtx;
    // 条件变量
    std::condition_variable not_full; // 通知生产者 缓冲区不满
    std::condition_variable not_empty; // 通知消费者 缓冲区不空
}instance; // 实例

// Because it takes a struct as a parameter 所以需要
typedef struct resource resource;


// 两个线程

// 生产者任务

// 输入全局变量 and currently being
void Produce(resource* ir,int item){
    
    std::unique_lock<std::mutex> lock(ir->mtx);

    // Determine the lock condition If the ring buffer goes back in The position of the write pointer has exceeded the read pointer
    while((ir->writePos+1)%buffsize == ir->readPos){
      
        // Consumers need to be reminded to consume
        std::cout<<"缓冲区满了,快来消费"<<endl;
        ir->not_full.wait(lock);  // Wait until the buffer is full 才能出来
        // 条件不满足时 Unlock automatically
    }
    // 出来之后 Start writing to the buffer
    // 正常生产
    (ir->buffer)[ir->writePos] = item;  //
    (ir->writePos)++;

    if(ir->writePos ==buffsize){
    
        ir->writePos = 0;
    }

    // After production is complete 通知消费者
    ir->not_empty.notify_all(); // The buffer is not empty anymore 快来消费

}

void produceTask(){
    
    for(int i=1;i<=proNum;++i){
    
        std::cout<<"生产者正在生产第"<<i<<"个产品"<<endl;
        // Then the task of the producer Mainly the implementation of the ring buffer
        Produce(&instance,i);
    }
}

int Consumer(resource *ir){
    
    int data;
    std::unique_lock<std::mutex> lock(ir->mtx);
    // 判断条件
    while(ir->readPos == ir->writePos){
    
        std::cout<<"Can you hurry up!"<<endl;
        ir->not_empty.wait(lock);  // Waiting is not empty
    }

    // formal consumption
    data = (ir->buffer)[ir->readPos];
    (ir->readPos)++;

    if(ir->readPos==buffsize){
    
        ir->readPos = 0;
    }

    ir->not_full.notify_all();  // Dissatisfaction can be notified after consumption  not_fullJust take the lock

    return data;

}

void consumerTask(){
    
    static int cnt = 0;  // 当前位置
    while(1){
    
        sleep(1);  // Consumers are slower
        int data = Consumer(&instance);
        std::cout<<"消费者正在消费第"<<data<<"个产品"<<endl;
        cnt++;
        if(cnt==proNum){
    
            break;
        }
    }
}


// 初始化

void initResource(resource *ir){
    
    ir->readPos = 0;
    ir->writePos = 0;
}

int main() {
    
    // 初始化
    initResource(&instance);

    // 两个线程
    std::thread produce(produceTask);
    std::thread consumer(consumerTask);

    produce.join();
    consumer.join();

    return 0;
}

交换打印10个AB

Mainly rely on condition variables and exclusive locks

std::mutex mtx;
std::condition_variable cv;
std::unique_lock<std::mutex> lock(mtx);
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>

using namespace std;


// 全局变量
std::mutex mtx;
std::condition_variable cv;
char flag = 'A';

// 打印A
void printA(){
    
    // 互斥锁

    for(int i=1;i<=10;++i) {
    
        std::this_thread::sleep_for(std::chrono::seconds(1)); // 睡眠一秒
        std::unique_lock<std::mutex> lock(mtx);
        while(flag=='B'){
    
            cv.wait(lock);
        }
        std::cout<<"第"<<i<<"个"<<flag<<endl;
        flag = 'B';
        cv.notify_all();
    }
}

// 打印B
void printB(){
    
    // 互斥锁

    for(int i=1;i<=10;++i) {
    
        std::this_thread::sleep_for(std::chrono::seconds(1)); // 睡眠一秒
 	    std::unique_lock<std::mutex> lock(mtx);
        while(flag=='A'){
    
            cv.wait(lock);
        }
        std::cout<<"第"<<i<<"个"<<flag<<endl;
        flag = 'A';
        cv.notify_all();
    }
}


int main() {
    

    // 多线程打印AB
    std::thread threadA(printA);
    std::thread threadB(printB);
    threadA.join();
    threadB.join();

    return 0;
}

手撕String类

#include <iostream>
#include <string.h>

using namespace std;

// 定义一个string类
// 有指针 Have to refactor the constructor etc
class String {
    
public:
    String(const char *str = nullptr); // Why use thisconst

    String(const String &other); // 拷贝构造
    ~String();

    String &operator=(const String &other);

    // 移动语义
    // 移动构造函数
    // To initialize an object containing a pointer type with a move instead of a deep copy
    String(String&& other);
    // 移动赋值函数
    String &operator=(String &&other);


private:
    char *m_data;
};

// 构造函数
// A constructor is an assignment to a variable
String::String(const char *str) {
    
    if (str == nullptr) {
    
        m_data = new char[1];
        *m_data = '\0';
    } else {
    
        int len = strlen(str);
        m_data = new char[len + 1];  // 因为char* 是\0 结尾的
        // 复制
        strcpy(m_data,str);
    }
    cout<<"构造函数"<<endl;
}

// 析构函数
// Frees the pointer element
String::~String() {
    
    delete[] m_data;
    m_data = nullptr;
    cout<<"析构函数"<<endl;
}

// 拷贝构造
// Assigns a variable with the specified element
String::String(const String &other) {
    
    int len = strlen(other.m_data);
    if(len==0){
    
        m_data = new char[1];
        *m_data = '\0';
    }else{
    
        m_data = new char[len + 1];  // 因为char* 是\0 结尾的
        // 复制
        strcpy(m_data,other.m_data);
    }
    cout<<"拷贝构造函数"<<endl;
}

// 赋值操作符
String & String::operator=(const String &other) {
    
    if(this == &other){
     // 这个我不太理解 this是指针 other是一个类 引用的形式
        return *this;
    }
    delete[] m_data;
    int len = strlen(other.m_data);
    m_data = new char[len + 1];  // 因为char* 是\0 结尾的
    // 复制
    strcpy(m_data,other.m_data);
    cout<<"拷贝赋值函数"<<endl;
    return *this;
    // 谁调用返回谁 strcpy const char* 转 char*
// this->m_data = other.m_data; 这样有什么问题?


}

// 移动构造函数
String::String(String &&other) {
     // 这个是const char* Move semantics cannot be addedconst
    m_data = other.m_data;
    other.m_data = nullptr;
    cout<<"移动构造函数"<<endl;
}

String & String::operator=(String &&other) {
    
    if(this==&other){
    
        return *this;
    }
    delete[] m_data;
    this->m_data = other.m_data;
    other.m_data = nullptr;

    cout<<"移动赋值函数"<<endl;
    return *this;
}

int main() {
    

    String s1;  // 构造函数
    String s5("hello world"); // 构造函数
    String s4; // 构造函数
    String s2(s1); // 拷贝构造函数
    String s3 = s1; // 拷贝构造函数
    s4 = s2; // 拷贝赋值函数
    String s6(std::move(s3));  // std:: move An lvalue becomes an rvalue 可以直接移动 不需要进行深拷贝 移动构造函数
    s3 = s1; // 拷贝赋值函数
    
    return 0;
}


}

LRU


排序算法(快排 堆排 归并)

快速排序

void quickSort(vector<int> &num,int l,int r){
    
    if(l+1 >= r) return; // 划分完毕
    int first = l,last = r-1,key = num[first];  // 选取first位置为比较点
    // 分成两个部分 后一部分 比前一部分要大
    while(first<last){
    

        while(first<last && num[last]>=key) last--; // 右指针 直到找到一个比key要小的数
        num[first] = num[last]; // 将这个数放到first的位置

        while(first<last && num[first]<=key) first++; // 左指针 直到找到一个比key要大的数
        num[last] = num[first]; // 将这个数放到first的位置

    }

    num[first] = key;  // 第一轮结束之后 key左边的数都下于它 右边的数都大于它
    quickSort(num,l,first); // 将左边的数快排
    quickSort(num,first+1,r); // 将右边的数快排
    // 直到全部结束
}

堆排序

void adjust(vector<int> &nums, int len, int index)
{
    int left = 2*index + 1;
    int right = 2*index + 2;
    int maxIdx = index;
    if(left<len && nums[left] > nums[maxIdx]) maxIdx = left;
    if(right<len && nums[right] > nums[maxIdx]) maxIdx = right;  // maxIdx是3个数中最大数的下标
    if(maxIdx != index)                 // 如果maxIdx的值有更新
    {
        swap(nums[maxIdx], nums[index]);
        adjust(nums, len, maxIdx);       // 递归调整其他不满足堆性质的部分
        
    }

}
void heapSort(vector<int>& nums, int size)
{
	// 对每一个非叶结点进行堆调整(从最后一个非叶结点开始) 
	// 比较所有父亲节点
    for(int i=size/2 - 1; i >= 0; i--)  
    {
        adjust(nums, size, i);
    }
    
    for(int i = size - 1; i >= 1; i--)
    {
        swap(nums[0], nums[i]);           // 将当前最大的放置到数组末尾
        adjust(nums, i, 0);              // 将未完成排序的部分继续进行堆排序
    }
}

归并排序

void merge(vector<int>&num,int l,int middle,int r){
    
    vector<int> tmp;
    int i=l;
    int j=middle+1;
    // 比较小的数据添加到临时数组里
    while(i<=middle && j<=r){
    
        if(num[i]<num[j]){
    
            tmp.push_back(num[i++]);
        }else{
    
            tmp.push_back(num[j++]);
        }
    }
    while(i<=middle){
    
        tmp.push_back(num[i++]);
    }
    while (j<=r){
    
        tmp.push_back(num[j++]);
    }
    for(int i=0;i<tmp.size();++i){
    
        num[l+i] = tmp[i];
    }
}

void mergeSort(vector<int>& num,int l,int r){
     // r是长度
    if(l==r) return;  //递归是让数组中的每个数单独成为长度为1的区间
    int middle = l + (r-l)/2; // 取中段
    // 分治
    mergeSort(num,l,middle);
    mergeSort(num,middle+1,r);
    merge(num,l,middle,r);

}

设计模式

Mainly write singleton pattern

#include <iostream>
#include <mutex>
#include <thread>

// Mainly write singleton pattern
// 懒汉模式
class lazy{
    
public:

    static pthread_mutex_t mtx;

    static lazy* instance(){
    
        // 不是线程安全的 If two threads make judgments at the same time 会错误 加锁解决
        pthread_mutex_lock(&mtx);
        if(la== nullptr){
      // 只初始化一次 调用的时候才初始化 第一次调用
            la = new lazy();
        }
        pthread_mutex_unlock(&mtx);
        return la;
    }

private:
    lazy();
    static lazy* la;

};
lazy* lazy::la = nullptr; // declared inside a static class 类外初始化
lazy::lazy() {
    
// pthread_mutex_init(&mtx);
}

// 饿汉模式
class hungry{
    
private:
    hungry(){
    }
    static hungry* hun;

public:
    static hungry* instance(){
      // 直接用
        return hun;
    }

};

hungry* hungry::hun = new hungry();


int main() {
    

    hungry * s = hungry::instance();
    
    return 0;
}


手写shared_ptr

#include <iostream>
#include <string>

using namespace std;

// shared_ptr是个模板类
template<typename T>
class sharedPtr{
    
public:
    // Class necessary functions
    // 无参构造函数
    sharedPtr();
    // 有参构造函数
    sharedPtr(T* p);
    // 拷贝构造
    sharedPtr(const sharedPtr<T>& other);
    // 赋值操作
    sharedPtr<T> &operator=(const sharedPtr<T>& other);
    // 指针的操作
    T* operator->(); // 返回指针

    T& operator*(); // 返回指针指向的对象 返回引用

    sharedPtr<T>& operator=(sharedPtr<T>& other);

    // 析构函数
    ~sharedPtr();

private:
    int * count; // 引用计数
    T* ptr; // 指针数据
};

// 无参构造函数
template<typename T>
sharedPtr<T>::sharedPtr():count(0),ptr(nullptr) {
    
    cout<<"执行无参构造函数"<<endl;
}  // 设置count 和 ptr 列表初始化

// 有参构造函数
template<typename T>
sharedPtr<T>::sharedPtr(T* p):count(new int(1)),ptr(p){
    
    cout<<"执行有参构造函数"<<endl;
}

// 拷贝构造
template<typename T>
sharedPtr<T>::sharedPtr(const sharedPtr<T> &other):count(&(++*other.count)),ptr(other.ptr) {
    
    cout<<"执行拷贝构造函数"<<endl;
}

// 赋值操作符
template<typename T>
sharedPtr<T> & sharedPtr<T>::operator=(sharedPtr<T> &other) {
    
    if(this==&other) return *this;
    ++*other.count++;
    // Whether the original object has an object
    if(this->ptr && 0==--*this->count){
    
        delete count;
        delete ptr;
        cout<<"delete ptr"<<endl;
    }
    this->ptr =  other.ptr;
    this->count = other.count;

    cout<<"执行赋值构造函数"<<endl;

    return *this;
}

// 指针操作
template<typename T>
T & sharedPtr<T>::operator*() {
    
    return *ptr;
}

template<typename T>
T * sharedPtr<T>::operator->() {
    
    return ptr;
}

// 析构函数
template<typename T>
sharedPtr<T>::~sharedPtr<T>() {
    

    cout<<"执行析构函数"<<endl;

    if(ptr && --*count==0){
    
        delete count;
        delete ptr;
        cout<<"delete ptr"<<endl;
    }
}

int main() {
    
    // 代码测试
    sharedPtr<int> s0;
    sharedPtr<int> s1(new int(1));
    sharedPtr<int> s2(s1);
    s0 = s1;
    
    return 0;
}

原网站

版权声明
本文为[20 to continue to work hard!]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/222/202208102233116987.html