2026美妆双11海报AI生图工具选型与批量实操指南
2026/10/11 6:52:34
#include<thread> #include<mutex> #include<condition_variable> void main() { condition_variable cv; mutex mtx; int x = 0, n = 0; cout << "请输入开始:"; cin >> x; cout << "请输入结束:"; cin >> n; thread t1([&, n]() { while (1) { unique_lock<mutex> lock(mtx); if (x >= n) break; if(x % 2 == 0) cv.wait(lock); //奇数 //cv.wait(lock, [&x]() { return x % 2 == 1; }); cout << this_thread::get_id() << ":" << x << endl; x++; cv.notify_one(); } }); thread t2([&, n]() { while (1) { unique_lock<mutex> lock(mtx); if (x > n) break; if (x % 2 != 0) cv.wait(lock); //偶数 //cv.wait(lock, [&x]() { return x % 2 == 0; }); cout << this_thread::get_id() << ":" << x << endl; ++x; cv.notify_one(); } }); t1.join(); t2.join(); } //C++也支持条件变量(不是线程安全的,所以要配合锁使用) //题目:两个线程交替打印,一个线程打印奇数,一个打印偶数 //condition_variable::wait 当前进程会进行阻塞,直到被唤醒,和linux一样,在阻塞之前会进行解锁,防止死锁问题,然后唤醒后重新申请锁 //文档中的 wait_for和wait_until表示等待的时间,notify_one和notify_all表示唤醒一个线程和唤醒所有线程 //如何做到t1和t2不管谁抢到锁都保证t1先运行,t2阻塞 --> t1不等待,t2有等待,这样t1获得了锁,t2就等着,t2获得了锁但是wait,释放锁,t1获得锁 //如何防止一个线程不断申请锁释放锁,不断运行?( t1打印的时候,释放锁并且通知t2,t2重新获得锁,但是t1没停下来又等待了,t1又获得了锁) --> t1, if(x%2 == 0) cv.wait(lock); t2,if (x % 2 != 0) cv.wait(lock); //为什么要防止一个线程连续打印? --> 假设t1,先获取到锁,t2后获取到锁,t2就阻塞在锁上面 --> t1打印奇数,++x,x变成偶数 --> t1 notift唤醒,但是没有线程wait(因为t1有锁,t2没有锁所以在阻塞等待) --> t1解锁,t1时间片到了,切出去了 // --> t2获取到锁,打印,notify,但是没有线程等待,t2再出作用域,解锁 --> t2的时间片充裕会比t1先获得锁,所以如果没有条件控制,就会导致t2连续打印#include <iostream> using namespace std; int main() { int a = 1; if (*(char*)&a == 1) //先取出a的地址,将其转化为char*后,此时再解引用就只会读取地址指向位置的第一个字节的数据 cout << "小端模式" << endl; else cout << "大端模式" << endl; return 0; }#include<iostream> #include<mutex> using namespace std; void* my_memcpy(void* p1, void* p2, unsigned int count) { if (!p1 || !p2) return NULL; char* pD = (char*)p1; char* pS = (char*)p2; if (pD <= pS || pD >= (pS + count)) while (count--) *pD++ = *pS++; else //处理内存重叠 { pD = (char*)p1 + count - 1; pS = (char*)p2 + count - 1; while (count--) *pD-- = *pS--; } return p1; } int main() { char tmpBuf[128] = "111111222222333333444444"; char destBuf[128] = { 0 }; std::cout << "1:" << (char*)my_memcpy(destBuf, tmpBuf, 10) << std::endl; std::cout << "2:" << destBuf << std::endl; std::cout << "3:" << (char*)my_memcpy(tmpBuf + 5, tmpBuf, 10) << std::endl; std::cout << "4:" << tmpBuf << std::endl; return 0; }namespace p1 { template<class T> class auto_ptr { public: auto_ptr(T* ptr = nullptr) :_ptr(ptr) {} auto_ptr(auto_ptr<T>&p) { _ptr = p._ptr; p._ptr = nullptr; } ~auto_ptr() { if (_ptr != nullptr) { cout << "delete: " << _ptr << endl; _ptr = nullptr; } } auto_ptr& operator=(auto_ptr<T>& ap) { if (this != &ap) { delete _ptr; //释放自己管理的资源 _ptr = ap._ptr; //接管ap对象的资源 ap._ptr = nullptr; //管理权转移后ap被置空 } return *this; } //可以像指针一样使用 T& operator*() { return *_ptr; } T* operator->() { return _ptr; } private: T* _ptr; }; } int main1() { p1::auto_ptr<int> p1(new int(1)); p1::auto_ptr<int> p2(p1); return 0; }namespace p2 { template<class T> class unique_ptr { unique_ptr(T* ptr = nullptr) :_ptr(ptr) {} ~unique_ptr() { if (_ptr != nullptr) { delete _ptr; cout << "delete: " << _ptr << endl; _ptr = nullptr; } } T& operator*() { return *_ptr; } T* operator->() { return _ptr; } unique_ptr(unique_ptr<T>& p) = delete; //直接禁用拷贝 unique_ptr& operator=(unique_ptr<T>& p) = delete; private: T* _ptr; }; }namespace p3 { template<class T> class shared_ptr { public: shared_ptr(T* ptr = nullptr) :_ptr(ptr) , _pcount(new int(1)) {} shared_ptr(shared_ptr<T>& sp) :_ptr(sp._ptr) , _pcount(sp._pcount) //拷贝时,获取对方的计数并++ { (*_pcount)++; } ~shared_ptr() { if (--(*_pcount) == 0) //如果为0,代表这是最后一次释放,需要delete { if (_ptr != nullptr) { delete _ptr; _ptr = nullptr; cout << "delete: " << _ptr << endl; } delete _pcount; _pcount = nullptr; } } shared_ptr& operator=(shared_ptr<T>& sp) { if (_ptr != sp._ptr) //管理同一块空间的对象之间无需进行赋值操作 { if (--(*_pcount) == 0) //将管理的资源对应的引用计数-- { delete _ptr; delete _pcount; cout << "delete: " << _ptr << endl; } _ptr = sp._ptr; //与sp对象一同管理它的资源 _pcount = sp._pcount; //获取sp对象管理的资源对应的引用计数 (*_pcount)++; //新增一个对象来管理该资源,引用计数++ } return *this; } //获取引用计数 int use_count() { return *_pcount; } T& operator*() { return *_ptr; } T* operator->() { return _ptr; } private: T* _ptr; //管理的资源 int* _pcount; //管理的资源对应的引用计数 }; }由于计数是建立在堆上的,一旦处于多线程环境可能会有线程安全问题,下面是线程安全版的shared_ptr:
namespace p3_thread_safe { template<class T> class shared_ptr { private: //++引用计数 void AddRef() { _pmutex->lock(); (*_pcount)++; _pmutex->unlock(); } //--引用计数 void ReleaseRef() { _pmutex->lock(); bool flag = false; if (--(*_pcount) == 0) //将管理的资源对应的引用计数-- { if (_ptr != nullptr) { cout << "delete: " << _ptr << endl; delete _ptr; _ptr = nullptr; } delete _pcount; _pcount = nullptr; flag = true; } _pmutex->unlock(); if (flag == true) { delete _pmutex; } } public: //RAII shared_ptr(T* ptr = nullptr) :_ptr(ptr) , _pcount(new int(1)) , _pmutex(new mutex) { } ~shared_ptr() { ReleaseRef(); } shared_ptr(shared_ptr<T>& sp) :_ptr(sp._ptr) , _pcount(sp._pcount) , _pmutex(sp._pmutex) { AddRef(); } shared_ptr& operator=(shared_ptr<T>& sp) { if (_ptr != sp._ptr) //管理同一块空间的对象之间无需进行赋值操作 { ReleaseRef(); //将管理的资源对应的引用计数-- _ptr = sp._ptr; //与sp对象一同管理它的资源 _pcount = sp._pcount; //获取sp对象管理的资源对应的引用计数 _pmutex = sp._pmutex; //获取sp对象管理的资源对应的互斥锁 AddRef(); //新增一个对象来管理该资源,引用计数++ } return *this; } //获取引用计数 int use_count() { return *_pcount; } //可以像指针一样使用 T& operator*() { return *_ptr; } T* operator->() { return _ptr; } private: T* _ptr; //管理的资源 int* _pcount; //管理的资源对应的引用计数 mutex* _pmutex; //管理的资源对应的互斥锁 }; }namespace p4 { template<class T> class weak_ptr { public: weak_ptr() :_ptr(nullptr) {} weak_ptr(const shared_ptr<T>& sp) :_ptr(sp.get()) {} weak_ptr& operator=(const shared_ptr<T>& sp) { _ptr = sp.get(); return *this; } //可以像指针一样使用 T& operator*() { return *_ptr; } T* operator->() { return _ptr; } private: T* _ptr; //管理的资源 }; }