c++ 线程交叉场景试验

1.需求

  1. 处理一个列表的数据,要求按照列表的顺序处理10个数据
  2. 可以使用多线程处理,但是针对每个线程,1~10的处理顺序不能变。
  3. 每个数据的处理必须原子,即只有一个线程可以针对某个数据进行处理,但是10个数据是可以由10个线程并行处理的。只是有前面的单线程内的处理顺序要求。

2.设计

2.1.设计说明

设计一个处理的监控链,为每个数据定义一个线程锁定的指针,叫锁定指针,表示数据已经被锁定,后续的线程需要排队。
为每个线程定义一个激活指针,如果有线程需要激活那么就通过该指针激活等待中的线程。
比如线程1开始处理数据1了,那么就把自己的指针设置给数据1的锁定指针
这时候如果线程2也想处数据1,会有两种情况,如下分别处理
情况1:数据没有任何线程锁定,那么按照线程1的方式处理数据1
情况2:线程1正在处理数据,那么我把我的指针设置给线程1的激活指针,同时把我的指针设置给数据1的锁定指针。这时候如果有线程3要处理数据1,处理的方和线程2的处理方法相同。

2.2.设计要点
  • 如果资源未被占用,那么锁资源,开始处理,由锁定指针承载。
  • 如果资源已经被占用了,所有等待的线程排队,形成一条激活链,由激活指针承载。

这个设计的关键就是两个指针,如下用类图说明。

类图如下:

3.代码

#include <iostream>  
#include <thread>  
#include <queue>
#include <mutex>  
#include <condition_variable>  
#include <atomic>  
#include <windows.h>  

using namespace std;
class BoxDatas; 
class MyThred;
std::mutex printmtx;

//数据处理对象
class Data
{
public:
    int id = 0;
    int count = 0;
};
class BoxData
{
public:
    Data data;
    BoxData(int id){
        data.id = id;
    }
    MyThred* handelThread = NULL;
    std::mutex mtx;
};

//数据容器承担多线程的处理对数据的保护功能
class BoxDatas
{
public:
    static BoxDatas my;
    static BoxDatas getMy() {
        return my;
    }
    static const int max = 10;
    BoxDatas() {
        for (int i = 0; i < max; i++)
        {
            bs[i] = new BoxData(i);
        }
    }
    BoxData* bs[max];
    //所有数据加工只都超过10可以结束线程
    bool isStop() {
        for (size_t i = 0; i < max; i++)
        {
            if (bs[i]->data.count < 10) {
                return false;
            }
        }
        return true;
    }
};

BoxDatas BoxDatas::my = BoxDatas();

 //线程承载类
class MyThred
{
public:
    int id;
    std::mutex mtx;
    std::condition_variable cv;
    std::atomic_bool ready = false;
    MyThred* p_next = nullptr;

    //构造函数
    MyThred(int id) {
        this->id = id;
    }

    //数据处理函数
    void funBox(BoxData* boxData) {
        DWORD threadId = GetCurrentThreadId();
        //如果已经有线程占用了,那么等待
        std::unique_lock<std::mutex> lock(boxData->mtx);//这个锁的目标是: boxData->handelThread
        if (boxData->handelThread != NULL) {
            std::unique_lock<std::mutex> lock2(boxData->handelThread->mtx);//这个锁的目标是:handelThread->p_next
            boxData->handelThread->p_next = this;
            boxData->handelThread = this;
            //lock2.unlock();
            lock.unlock();
            

            //cout <<"Thread id:"<< threadId <<"  data Id:" << boxData->data.id << "  wait \n";
            print(boxData->data.id, "wait");

            cv.wait(lock2);// 无条件激活等待的线程
            //cv.wait(lock2, [this](){ return ready.load(); }); // 等待直到ready为true  
        }
        else
        {
            boxData->handelThread = this;
            lock.unlock();
        }

        //cout << "Thread id:" << threadId << "  data Id :" << boxData->data.id << " exe \n";
        print(boxData->data.id,"exe");
        //数据处理
        dataProcessing(boxData->data);


        std::unique_lock<std::mutex> lock2(mtx);//这个锁的目标是:handelThread->p_next
        //处理完成后需要调用等待激活的线程
        if (p_next != nullptr) {
            p_next->activeThread();
        }
        else
        {
            std::unique_lock<std::mutex> lock3(boxData->mtx);//这个锁的目标是: boxData->handelThread
            boxData->handelThread = nullptr;
            lock3.unlock();
        }
        lock2.unlock();
    }
    //数据处理逻辑
    void dataProcessing(Data& data) {

        //加一个延时填充线程执行占用的时间
        //std::this_thread::sleep_for(std::chrono::seconds(5));
        data.count++;
        DWORD threadId = GetCurrentThreadId();
        //cout << "Thread id:" << id << "  data Id:" << data.id <<"  data value:"<< data.count << "  value \n";
        print(data.id,"value", data.count);
    }

    void print(int dataId,std::string funType) {
        DWORD threadId = GetCurrentThreadId();
        std::unique_lock<std::mutex> lock(printmtx);
        cout << "Thread id:" << threadId << "  data Id:" << dataId << "  " << funType << "\n";
        lock.unlock();
    }
    void print(int dataId, std::string funType,int value) {
        DWORD threadId = GetCurrentThreadId();
        std::unique_lock<std::mutex> lock(printmtx);
        cout << "Thread id:" << threadId << "  data Id:" << dataId << "  data value:"<< value <<"  " << funType << "\n";
        lock.unlock();
    }
    //此线程激活
    void activeThread() {
        ready = true;
        cv.notify_one(); // 唤醒一个等待在cv上的线程(如果有的话)
    }
    //线程主函数
    void mainThread() {
        while (true)
        {
            for(BoxData* bd : BoxDatas::getMy().bs)
            {
                funBox(bd);
            }
            //如果完成了数据,那么退出
            if (BoxDatas::getMy().isStop()) {
                break;
            }
        }
    }
    //线程运行
    std::thread run() {
        return std::thread([this] {mainThread(); });
    }
};

//入口函数
int main() {
    std::thread threads[5];

    //线程初始化
    for (int i = 0; i < 5; i++)
    {
        MyThred thrend(i);
        threads[i] = thrend.run();
    }

    //防止程序提取退出
    for (size_t i = 0; i < 5; i++)
    {
        threads[i].join();
    }

    std::cout << "Hello from thread!\n";
    return 0;
}

4.运行结果

Thread id:15512  data Id:0  exe
Thread id:19512  data Id:0  wait
Thread id:15512  data Id:0  data value:1  value
Thread id:9320  data Id:0  wait
Thread id:10556  data Id:0  wait
Thread id:15512  data Id:1  exe
Thread id:25516  data Id:0  wait
Thread id:15512  data Id:1  data value:1  value
Thread id:19512  data Id:0  exe
Thread id:15512  data Id:2  exe
Thread id:9320  data Id:0  exe
Thread id:19512  data Id:0  data value:2  value
Thread id:15512  data Id:2  data value:1  value
Thread id:9320  data Id:0  data value:3  value
Thread id:19512  data Id:1  wait
Thread id:10556  data Id:0  exe
Thread id:15512  data Id:3  exe
Thread id:9320  data Id:1  wait
Thread id:10556  data Id:0  data value:4  value
Thread id:15512  data Id:3  data value:1  value
Thread id:19512  data Id:1  exe
Thread id:25516  data Id:0  exe
Thread id:10556  data Id:1  wait
Thread id:19512  data Id:1  data value:2  value
Thread id:25516  data Id:0  data value:5  value
Thread id:9320  data Id:1  exe
Thread id:15512  data Id:4  exe
Thread id:10556  data Id:1  exe
Thread id:19512  data Id:2  wait
Thread id:9320  data Id:1  data value:3  value
Thread id:15512  data Id:4  data value:1  value
Thread id:10556  data Id:1  data value:4  value
Thread id:25516  data Id:1  wait
Thread id:19512  data Id:2  exe
Thread id:9320  data Id:2  wait
Thread id:19512  data Id:2  data value:2  value
Thread id:10556  data Id:2  wait
Thread id:15512  data Id:5  exe
Thread id:15512  data Id:5  data value:1  value
Thread id:25516  data Id:1  exe
Thread id:25516  data Id:1  data value:5  value
Thread id:9320  data Id:2  exe
Thread id:9320  data Id:2  data value:3  value
Thread id:19512  data Id:3  wait
Thread id:10556  data Id:2  exe
Thread id:15512  data Id:6  exe
Thread id:15512  data Id:6  data value:1  value
Thread id:10556  data Id:2  data value:4  value
Thread id:25516  data Id:2  wait
Thread id:19512  data Id:3  exe
Thread id:9320  data Id:3  wait
Thread id:19512  data Id:3  data value:2  value
Thread id:10556  data Id:3  wait
Thread id:15512  data Id:7  exe
Thread id:15512  data Id:7  data value:1  value
Thread id:25516  data Id:2  exe
Thread id:25516  data Id:2  data value:5  value
Thread id:9320  data Id:3  exe
Thread id:9320  data Id:3  data value:3  value
Thread id:19512  data Id:4  wait
Thread id:10556  data Id:3  exe
Thread id:10556  data Id:3  data value:4  value
Thread id:25516  data Id:3  wait
Thread id:19512  data Id:4  exe
Thread id:19512  data Id:4  data value:2  value
Thread id:9320  data Id:4  wait
Thread id:25516  data Id:3  exe
Thread id:25516  data Id:3  data value:5  value
Thread id:10556  data Id:4  wait
Thread id:15512  data Id:8  exe
Thread id:15512  data Id:8  data value:1  value
Thread id:19512  data Id:5  wait
Thread id:9320  data Id:4  exe
Thread id:9320  data Id:4  data value:3  value
Thread id:25516  data Id:4  wait
Thread id:10556  data Id:4  exe
Thread id:10556  data Id:4  data value:4  value
Thread id:15512  data Id:9  exe
Thread id:15512  data Id:9  data value:1  value
Thread id:19512  data Id:5  exe
Thread id:19512  data Id:5  data value:2  value
Thread id:9320  data Id:5  wait
Thread id:25516  data Id:4  exe
Thread id:10556  data Id:5  wait
Thread id:25516  data Id:4  data value:5  value
Thread id:19512  data Id:6  wait
Thread id:15512  data Id:0  wait
Thread id:9320  data Id:5  exe
Thread id:9320  data Id:5  data value:3  value
Thread id:25516  data Id:5  wait
Thread id:10556  data Id:5  exe
Thread id:10556  data Id:5  data value:4  value
Thread id:19512  data Id:6  exe
Thread id:9320  data Id:6  wait
Thread id:15512  data Id:0  exe
Thread id:19512  data Id:6  data value:2  value
Thread id:25516  data Id:5  exe
Thread id:10556  data Id:6  wait
Thread id:15512  data Id:0  data value:6  value
Thread id:25516  data Id:5  data value:5  value
Thread id:9320  data Id:6  exe
Thread id:19512  data Id:7  wait
Thread id:9320  data Id:6  data value:3  value
Thread id:10556  data Id:6  exe
Thread id:15512  data Id:1  wait
Thread id:10556  data Id:6  data value:4  value
Thread id:19512  data Id:7  exe
Thread id:25516  data Id:6  wait
Thread id:19512  data Id:7  data value:2  value
Thread id:15512  data Id:1  exe
Thread id:9320  data Id:7  wait
Thread id:15512  data Id:1  data value:6  value
Thread id:25516  data Id:6  exe
Thread id:25516  data Id:6  data value:5  value
Thread id:10556  data Id:7  wait
Thread id:9320  data Id:7  exe
Thread id:19512  data Id:8  wait
Thread id:9320  data Id:7  data value:3  value
Thread id:25516  data Id:7  wait
Thread id:15512  data Id:2  wait
Thread id:10556  data Id:7  exe
Thread id:10556  data Id:7  data value:4  value
Thread id:9320  data Id:8  wait
Thread id:19512  data Id:8  exe
Thread id:19512  data Id:8  data value:2  value
Thread id:25516  data Id:7  exe
Thread id:25516  data Id:7  data value:5  value
Thread id:15512  data Id:2  exe
Thread id:15512  data Id:2  data value:6  value
Thread id:10556  data Id:8  wait
Thread id:9320  data Id:8  exe
Thread id:9320  data Id:8  data value:3  value
Thread id:19512  data Id:9  wait
Thread id:15512  data Id:3  wait
Thread id:25516  data Id:8  wait
Thread id:19512  data Id:9  exe
Thread id:19512  data Id:9  data value:2  value
Thread id:15512  data Id:3  exe
Thread id:9320  data Id:9  wait
Thread id:10556  data Id:8  exe
Thread id:10556  data Id:8  data value:4  value
Thread id:25516  data Id:8  exe
Thread id:19512  data Id:0  wait
Thread id:15512  data Id:3  data value:6  value
Thread id:25516  data Id:8  data value:5  value
Thread id:9320  data Id:9  exe
Thread id:10556  data Id:9  wait
Thread id:9320  data Id:9  data value:3  value
Thread id:19512  data Id:0  exe
Thread id:19512  data Id:0  data value:7  value
Thread id:15512  data Id:4  wait
Thread id:10556  data Id:9  exe
Thread id:25516  data Id:9  wait
Thread id:10556  data Id:9  data value:4  value
Thread id:19512  data Id:1  wait
Thread id:9320  data Id:0  wait
Thread id:15512  data Id:4  exe
Thread id:15512  data Id:4  data value:6  value
Thread id:10556  data Id:0  wait
Thread id:25516  data Id:9  exe
Thread id:9320  data Id:0  exe
Thread id:19512  data Id:1  exe
Thread id:19512  data Id:1  data value:7  value
Thread id:25516  data Id:9  data value:5  value
Thread id:9320  data Id:0  data value:8  value
Thread id:15512  data Id:5  wait
Thread id:10556  data Id:0  exe
Thread id:10556  data Id:0  data value:9  value
Thread id:19512  data Id:2  wait
Thread id:9320  data Id:1  wait
Thread id:25516  data Id:0  wait
Thread id:19512  data Id:2  exe
Thread id:15512  data Id:5  exe
Thread id:9320  data Id:1  exe
Thread id:10556  data Id:1  wait
Thread id:19512  data Id:2  data value:7  value
Thread id:15512  data Id:5  data value:6  value
Thread id:9320  data Id:1  data value:8  value
Thread id:25516  data Id:0  exe
Thread id:25516  data Id:0  data value:10  value
Thread id:19512  data Id:3  wait
Thread id:10556  data Id:1  exe
Thread id:10556  data Id:1  data value:9  value
Thread id:15512  data Id:6  wait
Thread id:25516  data Id:1  wait
Thread id:9320  data Id:2  wait
Thread id:15512  data Id:6  exe
Thread id:15512  data Id:6  data value:6  value
Thread id:25516  data Id:1  exe
Thread id:25516  data Id:1  data value:10  value
Thread id:19512  data Id:3  exe
Thread id:10556  data Id:2  wait
Thread id:19512  data Id:3  data value:7  value
Thread id:9320  data Id:2  exe
Thread id:15512  data Id:7  wait
Thread id:9320  data Id:2  data value:8  value
Thread id:10556  data Id:2  exe
Thread id:25516  data Id:2  wait
Thread id:10556  data Id:2  data value:9  value
Thread id:15512  data Id:7  exe
Thread id:19512  data Id:4  wait
Thread id:15512  data Id:7  data value:6  value
Thread id:25516  data Id:2  exe
Thread id:25516  data Id:2  data value:10  value
Thread id:9320  data Id:3  wait
Thread id:19512  data Id:4  exe
Thread id:10556  data Id:3  wait
Thread id:19512  data Id:4  data value:7  value
Thread id:25516  data Id:3  wait
Thread id:15512  data Id:8  wait
Thread id:9320  data Id:3  exe
Thread id:9320  data Id:3  data value:8  value
Thread id:19512  data Id:5  wait
Thread id:10556  data Id:3  exe
Thread id:15512  data Id:8  exe
Thread id:25516  data Id:3  exe
Thread id:9320  data Id:4  wait
Thread id:10556  data Id:3  data value:9  value
Thread id:10556  data Id:4  wait
Thread id:25516  data Id:3  data value:10  value
Thread id:19512  data Id:5  exe
Thread id:15512  data Id:8  data value:6  value
Thread id:9320  data Id:4  exe
Thread id:9320  data Id:4  data value:8  value
Thread id:19512  data Id:5  data value:7  value
Thread id:25516  data Id:4  wait
Thread id:10556  data Id:4  exe
Thread id:15512  data Id:9  wait
Thread id:10556  data Id:4  data value:9  value
Thread id:19512  data Id:6  wait
Thread id:9320  data Id:5  wait
Thread id:25516  data Id:4  exe
Thread id:10556  data Id:5  wait
Thread id:25516  data Id:4  data value:10  value
Thread id:15512  data Id:9  exe
Thread id:15512  data Id:9  data value:6  value
Thread id:19512  data Id:6  exe
Thread id:25516  data Id:5  wait
Thread id:9320  data Id:5  exe
Thread id:9320  data Id:5  data value:8  value
Thread id:10556  data Id:5  exe
Thread id:10556  data Id:5  data value:9  value
Thread id:19512  data Id:6  data value:7  value
Thread id:15512  data Id:0  wait
Thread id:25516  data Id:5  exe
Thread id:9320  data Id:6  wait
Thread id:25516  data Id:5  data value:10  value
Thread id:19512  data Id:7  wait
Thread id:10556  data Id:6  wait
Thread id:15512  data Id:0  exe
Thread id:15512  data Id:0  data value:11  value
Thread id:25516  data Id:6  wait
Thread id:9320  data Id:6  exe
Thread id:9320  data Id:6  data value:8  value
Thread id:19512  data Id:7  exe
Thread id:19512  data Id:7  data value:7  value
Thread id:10556  data Id:6  exe
Thread id:10556  data Id:6  data value:9  value
Thread id:15512  data Id:1  wait
Thread id:25516  data Id:6  exe
Thread id:25516  data Id:6  data value:10  value
Thread id:9320  data Id:7  wait
Thread id:10556  data Id:7  wait
Thread id:19512  data Id:8  wait
Thread id:9320  data Id:7  exe
Thread id:9320  data Id:7  data value:8  value
Thread id:10556  data Id:7  exe
Thread id:25516  data Id:7  wait
Thread id:15512  data Id:1  exe
Thread id:15512  data Id:1  data value:11  value
Thread id:19512  data Id:8  exe
Thread id:19512  data Id:8  data value:7  value
Thread id:10556  data Id:7  data value:9  value
Thread id:9320  data Id:8  wait
Thread id:25516  data Id:7  exe
Thread id:15512  data Id:2  wait
Thread id:25516  data Id:7  data value:10  value
Thread id:10556  data Id:8  wait
Thread id:19512  data Id:9  wait
Thread id:9320  data Id:8  exe
Thread id:9320  data Id:8  data value:8  value
Thread id:25516  data Id:8  wait
Thread id:15512  data Id:2  exe
Thread id:15512  data Id:2  data value:11  value
Thread id:10556  data Id:8  exe
Thread id:10556  data Id:8  data value:9  value
Thread id:19512  data Id:9  exe
Thread id:19512  data Id:9  data value:7  value
Thread id:9320  data Id:9  wait
Thread id:25516  data Id:8  exe
Thread id:25516  data Id:8  data value:10  value
Thread id:15512  data Id:3  wait
Thread id:19512  data Id:0  wait
Thread id:10556  data Id:9  wait
Thread id:15512  data Id:3  exe
Thread id:15512  data Id:3  data value:11  value
Thread id:19512  data Id:0  exe
Thread id:19512  data Id:0  data value:12  value
Thread id:9320  data Id:9  exe
Thread id:9320  data Id:9  data value:8  value
Thread id:25516  data Id:9  wait
Thread id:10556  data Id:9  exe
Thread id:10556  data Id:9  data value:9  value
Thread id:15512  data Id:4  wait
Thread id:9320  data Id:0  wait
Thread id:19512  data Id:1  wait
Thread id:15512  data Id:4  exe
Thread id:15512  data Id:4  data value:11  value
Thread id:9320  data Id:0  exe
Thread id:9320  data Id:0  data value:13  value
Thread id:25516  data Id:9  exe
Thread id:25516  data Id:9  data value:10  value
Thread id:10556  data Id:0  wait
Thread id:19512  data Id:1  exe
Thread id:19512  data Id:1  data value:12  value
Thread id:15512  data Id:5  wait
Thread id:10556  data Id:0  exe
Thread id:10556  data Id:0  data value:14  value
Thread id:9320  data Id:1  wait
Thread id:15512  data Id:5  exe
Thread id:15512  data Id:5  data value:11  value
Thread id:19512  data Id:2  wait
Thread id:9320  data Id:1  exe
Thread id:9320  data Id:1  data value:13  value
Thread id:10556  data Id:1  wait
Thread id:19512  data Id:2  exe
Thread id:19512  data Id:2  data value:12  value
Thread id:15512  data Id:6  wait
Thread id:10556  data Id:1  exe
Thread id:10556  data Id:1  data value:14  value
Thread id:9320  data Id:2  wait
Thread id:15512  data Id:6  exe
Thread id:15512  data Id:6  data value:11  value
Thread id:19512  data Id:3  wait
Thread id:9320  data Id:2  exe
Thread id:9320  data Id:2  data value:13  value
Thread id:10556  data Id:2  wait
Thread id:19512  data Id:3  exe
Thread id:19512  data Id:3  data value:12  value
Thread id:15512  data Id:7  wait
Thread id:10556  data Id:2  exe
Thread id:10556  data Id:2  data value:14  value
Thread id:9320  data Id:3  wait
Thread id:15512  data Id:7  exe
Thread id:15512  data Id:7  data value:11  value
Thread id:19512  data Id:4  wait
Thread id:9320  data Id:3  exe
Thread id:9320  data Id:3  data value:13  value
Thread id:10556  data Id:3  wait
Thread id:19512  data Id:4  exe
Thread id:19512  data Id:4  data value:12  value
Thread id:15512  data Id:8  wait
Thread id:10556  data Id:3  exe
Thread id:10556  data Id:3  data value:14  value
Thread id:9320  data Id:4  wait
Thread id:15512  data Id:8  exe
Thread id:15512  data Id:8  data value:11  value
Thread id:19512  data Id:5  wait
Thread id:9320  data Id:4  exe
Thread id:9320  data Id:4  data value:13  value
Thread id:10556  data Id:4  wait
Thread id:19512  data Id:5  exe
Thread id:19512  data Id:5  data value:12  value
Thread id:15512  data Id:9  wait
Thread id:10556  data Id:4  exe
Thread id:10556  data Id:4  data value:14  value
Thread id:9320  data Id:5  wait
Thread id:15512  data Id:9  exe
Thread id:15512  data Id:9  data value:11  value
Thread id:19512  data Id:6  wait
Thread id:9320  data Id:5  exe
Thread id:9320  data Id:5  data value:13  value
Thread id:10556  data Id:5  wait
Thread id:19512  data Id:6  exe
Thread id:19512  data Id:6  data value:12  value
Thread id:9320  data Id:6  wait
Thread id:10556  data Id:5  exe
Thread id:10556  data Id:5  data value:14  value
Thread id:19512  data Id:7  wait
Thread id:9320  data Id:6  exe
Thread id:10556  data Id:6  wait
Thread id:9320  data Id:6  data value:13  value
Thread id:19512  data Id:7  exe
Thread id:19512  data Id:7  data value:12  value
Thread id:9320  data Id:7  wait
Thread id:10556  data Id:6  exe
Thread id:10556  data Id:6  data value:14  value
Thread id:19512  data Id:8  wait
Thread id:9320  data Id:7  exe
Thread id:9320  data Id:7  data value:13  value
Thread id:10556  data Id:7  wait
Thread id:19512  data Id:8  exe
Thread id:19512  data Id:8  data value:12  value
Thread id:9320  data Id:8  wait
Thread id:10556  data Id:7  exe
Thread id:10556  data Id:7  data value:14  value
Thread id:19512  data Id:9  wait
Thread id:9320  data Id:8  exe
Thread id:9320  data Id:8  data value:13  value
Thread id:10556  data Id:8  wait
Thread id:19512  data Id:9  exe
Thread id:19512  data Id:9  data value:12  value
Thread id:9320  data Id:9  wait
Thread id:10556  data Id:8  exe
Thread id:10556  data Id:8  data value:14  value
Thread id:10556  data Id:9  wait
Thread id:9320  data Id:9  exe
Thread id:9320  data Id:9  data value:13  value
Thread id:10556  data Id:9  exe
Thread id:10556  data Id:9  data value:14  value
Hello from thread!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值