淘优惠

淘优惠

1.互斥体 ACE_Thread_Mutex

热门文章 0

2023年11月20日 每日一猜答案: 答案:ABC
每日一猜答案分析:


1. 设置环境变量 在操作系统添加一个名为ACE_ROOT的用户环境变量,值为刚才ace的解压路径D:\Develop\ACE_wrappers。 添加用户的Path环境变量,值为%ACE_ROOT%\lib,这样才能保证系统能找到ace生成的动态连接库。 设置VS2005的C++开发项目信息,依次打开菜单 工具-选项-项目和解决方案-VC++目录 ,在右侧目录列表中选择"包含目录",添加$(ACE_ROOT),在右侧目录列表中选择"库文件",添加$(ACE_ROOT)\lib。2. 在 ACE_wrappers\ace 目录下创建 config.h 文件,写入: #include "ace/config-win32.h"? Code3.?如果你希望使用标准的?C++?头文件(例如?iostream、cstdio?等)在?#include?"ace/config-win32.h"?前加入:?#define?ACE_HAS_STANDARD_CPP_LIBRARY?1?4.?如果你希望使用?MFC?库,那么?config.h?中加入:?#define?ACE_HAS_MFC?1?如果你希望使用?MFC?静态库,那么加入:?#define?ACE_USES_STATIC_MFC?5.?如果你希望编译静态版本的?ACE?库,那么在?config.h?中加入:?#define?ACE_AS_STATIC_LIBS?6.?如果你希望减少静态库的大小,可以禁止使用?inline,在?config.h?的?#include?"ace/config-win32.h"?前加入:?#define?ACE_NO_INLINE? ? 1)ACE OS adaptation 层:封装了 OS API,对上层提供 OS 平台无关的接口。 2)C++ wrapper facades 层:位于 OS adaptation 之上,提供了与之相似的功能,这些功能使用 C++ 的类封装起来,而不是 C 语言 API。每个 wrapper facade 都包含一个或者一个以上的类。我们可以有选择的继承、聚合这些 wrapper facade。 3)框架层(Framework layer) 框架层在 C++ wrapper facades 层之上,它集成和扩充了 wrapper facade 类。 <1> 事件多路分离和分发框架 ACE Reactor 和 ACE Proactor 实现了 Reactor 模式和 Proactor 模式。 <2> 连接建立和服务初始化框架 ACE Acceptor-Connector 框架实现了 Acceptor-Connector 模式。 <3> 并发框架 ACE 提供了 Task 框架实现了并发模式。 <4> 服务配置框架 ACE 的服务配置框架实现了 Component Configurator 模式。 <5> 流框架 ACE 的流框架实现了 Pipes and Fiters 模式。 4)ACE 网络组件层 组件(component)就是软件系统中被封装的一个部分,ACE 发行包中的组件用于提供以下功能: <1> 演示 ACE <2> 提供常见网络服务的可复用实现。如提供日志记录、时间同步等服务的可复用实现。 ? 一. 线程入口函数 所有线程必须从一个指定的函数开始执行,该函数称为线程函数,它必须具有下列原型: void* worker(void *arg) {} 该函数输入一个void *型的参数,可以在创建线程时传入。 注意:所有的线程启动函数(方法)必须是静态的或全局的(就如同直接使用OS线程API时所要求的一样)。 二.线程基本操作 1.创建一个线程 一个进程的主线程是由操作系统自动生成,如果你要让一个主线程创建额外的线程,可以通过ACE_Thread::spawn()实现,该函数一般的使用方式如下: ACE_thread_t threadId; ACE_hthread_t threadHandle; ACE_Thread::spawn( (ACE_THR_FUNC)worker, //线程执行函数 NULL, //执行函数参数 THR_JOINABLE | THR_NEW_LWP, &threadId, &threadHandle ); ACE_Thread::spawn((ACE_THR_FUNC)worker) 使用其默认参数,来创建一个worker的线程。 ACE_Thread::spawn_n函数来创建多个线程。 2.终止线程 在线程函数体中ACE_Thread::exit()调用即可终止线程执行。 3.设定线程的相对优先级 当一个线程被首次创建时,它的优先级等同于它所属进程的优先级。一个线程的优先级是相对于其所属的进程的优先级而言的。可以通过调用ACE_Thread::setprio函数改变线程的相对优先级,该函数的调用方式如下: ACE_Thread::setprio(threadHandle,ACE_DEFAULT_THREAD_PRIORITY) 4.挂起及恢复线程 挂起线程可以通过来实现,它能暂停一个线程的执行,其调用方式如下ACE_Thread::suspend(threadHandle) 。 相应的,可以通过ACE_Thread::resume(threadHandle) 恢复被挂起的线程的执行。 5.等待线程结束 在主函数中调用ACE_Thread::join(threadHandle)可阻塞主函数,直道线程结束才能继续执行。 6.停止线程 在主函数中调用ACE_Thread::cancel (threadHandle)可停止线程的执行(在Unix底下可以,而在windows下好像不起作用,有待检验)。 三.程序示例 下面例子演示了如何用ace创建一个线程。 #include "ace/Thread.h" #include "ace/Synch.h"#pragma comment(lib, "ACEd.lib")#include <iostream> using namespace std; void* worker(void *arg) { for(int i=0;i<10;i++){ACE_OS::sleep(1);cout<<endl<<"hello world"<<endl;} return NULL; } int main(int argc, char *argv[]) { ACE_thread_t threadId;ACE_hthread_t threadHandle;ACE_Thread::spawn((ACE_THR_FUNC)worker, //线程执行函数NULL, //执行函数参数THR_JOINABLE | THR_NEW_LWP,&threadId,&threadHandle);ACE_Thread::join(threadHandle); return 0; } 在这个简单的例子中,创建了1个工作者线程,执行程序中定义的worker()函数。然后阻塞主函数,待线程结束后退出程序。 锁类属包含的类包装简单的锁定机制,比如互斥体、信号量、读/写互斥体和令牌等。这里我就以互斥体为例简单的介绍一下其使用方法,对其它的锁类进行一些简单的说明。 互斥体用于保护共享的易变代码,也就是全局或静态数据。这样的数据必须通过互斥体进行保护,以防止它们在多个线程同时访问时损坏。 #include "ace/Thread.h" #include "ace/Synch.h" #include <iostream> using namespace std; ACE_Thread_Mutex mutex; void* Thread1(void *arg) {mutex.acquire();ACE_OS::sleep(3);cout<<endl<<"hello thread1"<<endl;mutex.release(); return NULL; } void* Thread2(void *arg) {mutex.acquire();cout<<endl<<"hello thread2"<<endl;mutex.release(); return NULL; } int main(int argc, char *argv[]) { ACE_Thread::spawn((ACE_THR_FUNC)Thread1); //Thread2 比Thread1晚创建1秒钟,故后尝试获取互斥体ACE_OS::sleep(1);ACE_Thread::spawn((ACE_THR_FUNC)Thread2); while(true)ACE_OS::sleep(10); return 0; } ACE_Thread_Mutex主要有两个方法: acquire():用来获取互斥体,如果无法获取,将阻塞至获取到为止。 release():用来释放互斥体,从而使自己或者其它线程能够获取互斥体。 当线程要访问共享资源时,首先调用acquire()方法获取互斥体,从而获取对改互斥体所保护的共享资源的唯一访问权限,访问结束时调用释放互斥体,使得其它线程能获取共享资源的访问权限。 2.ACE Lock类属简介。 ACE Lock类属列表如下: ACE_Mutex 封装互斥机制(根据平台,可以是mutex_t、pthread_mutex_t等等)的包装类,用于提供简单而有效的机制来使对共享资源的访问序列化。它与二元信号量(binary semaphore)的功能相类似。可被用于线程和进程间的互斥。 ACE_Thread_Mutex 可用于替换ACE_Mutex,专用于线程同步。 ACE_Process_Mutex 可用于替换ACE_Mutex,专用于进程同步。 ACE_NULL_Mutex 提供了ACE_Mutex接口的"无为"(do-nothing)实现,可在不需要同步时用作替换。 ACE_RW_Mutex 封装读者/作者锁的包装类。它们是分别为读和写进行获取的锁,在没有作者在写的时候,多个读者可以同时进行读取。 ACE_RW_Thread_Mutex 可用于替换ACE_RW_Mutex,专用于线程同步。 ACE_RW_Process_Mutex 可用于替换ACE_RW_Mutex,专用于进程同步。 ACE_Semaphore 这些类实现计数信号量,在有固定数量的线程可以同时访问一个资源时很有用。在OS不提供这种同步机制的情况下,可通过互斥体来进行模拟。 ACE_Thread_Semaphore 应被用于替换ACE_Semaphore,专用于线程同步。 ACE_Process_Semaphore 应被用于替换ACE_Semaphore,专用于进程同步。 ACE_Token 提供"递归互斥体"(recursive mutex),也就是,当前持有某令牌的线程可以多次重新获取它,而不会阻塞。而且,当令牌被释放时,它确保下一个正阻塞并等待此令牌的线程就是下一个被放行的线程。 ACE_Null_Token 令牌接口的"无为"(do-nothing)实现,在你知道不会出现多个线程时使用。 ACE_Lock 定义锁定接口的接口类。一个纯虚类,如果使用的话,必须承受虚函数调用开销。 ACE_Lock_Adapter 基于模板的适配器,允许将前面提到的任意一种锁定机制适配到ACE_Lock接口。 可以简单的分为以下几类: 互斥锁 互斥锁(通常称为"互斥体"或"二元信号量")用于保护多线程控制并发访问的共享资源的完整性。互斥体通过定义临界区来序列化多线程控制的执行,在临界区中每一时刻只有一个线程在执行它的代码。互斥体简单而高效(时间和空间)。 ACE线程库提供了Mutex式的类(是一组互斥体对象,拥有类似的接口),他是一种简单而高效的类型是"非递归"互斥体。非递归互斥体不允许当前拥有互斥体的线程在释放它之前重新获取它。否则,将会立即发生死锁。递归互斥体在ACE Recursive_Thread_Mutex类中可移植地实现。 读者/作者锁 读者/作者锁与互斥体相类似。例如,获取读者/作者锁的线程也必须释放它。多个线程可同时获取一个读者/作者锁用于读,但只有一个线程可以获取该锁用于写。当互斥体保护的资源用于读远比用于写要频繁时,读者/作者互斥体有助于改善并发的执行。 ACE线程库提供了一个叫作RW_Mutex的类,在C++封装类中可移植地实现了读者/作者锁的语义。读者/作者锁将优先选择权给作者。因而,如果有多个读者和一个作者在锁上等待,作者将会首先获取它。 计数信号量 在概念上,计数信号量是可以原子地增减的整数。如果线程试图减少一个值为零的信号量的值,它就会阻塞,直到另一个线程增加该信号量的值。 计数信号量用于追踪共享程序状态的变化。它们记录某种特定事件的发生。因为信号量维护状态,它们允许线程根据该状态来作决定,即使事件是发生在过去。 信号量比互斥体效率要低,但是,它们要更为通用,因为它们无需被最初获取它们的同一线程获取和释放。这使得它们能够用于异步的执行上下文中(比如信号处理器)。ACE线程库提供一个叫作Semaphore的类来可移植地在C++包装类中实现信号量语义。 与C一级的互斥体API相比较,Mutex包装为同步多线程控制提供了一种优雅的接口。但是,Mutex潜在地容易出错,因为程序员有可能忘记调用release方法(当然,C级的互斥体API更容易出错)。这可能由于程序员的疏忽或是C++异常的发生而发生,然而,其导致及其严重的后果--死锁。 因此,为改善应用的健壮性,ACE同步机制有效地利用C++类构造器和析构器的语义来确保Mutex锁被自动获取和释放。 ACE提供了一个称为Guard、Write_Guard和Read_Guard的类族,确保在进入和退出C++代码块时分别自动获取和释放锁。 Guard类是最基本的守卫机制,定义可以简化如下(实际定义比这相对要复杂而完善一点): template <class LOCK> class Guard { public: ? Guard (LOCK &l): lock_ (&l){ lock_.acquire (); } ? ?Guard (void) {? lock_.release (); } private: ? LOCK lock_; } Guard类的对象定义一"块"代码,在其上锁被自动获取,并在退出块时自动释放,即使是程序抛异常也能保证自动解锁。这种机制也能为Mutex、RW_Mutex和Semaphore同步封装工作。 对于读写锁,由于加锁接口不一样,ace也提供了相应的Read_Guard和Write_Guard类,Read_Guard和Write_Guard类有着与Guard类相同的接口。但是,它们的acquire方法分别对锁进行读和写。 缺省地, Guard类构造器将会阻塞程序,直到锁被获取。会有这样的情况,程序必须使用非阻塞的acquire调用(例如,防止死锁)。因此,可以传给ACE Guard的构造器第二个参数(请参看原始代码,而不是我这里的简化代码),指示它使用锁的try_acquire方法,而不是acquire。随后调用者可以使用Guard的locked方法来原子地测试实际上锁是否已被获取。 用Guard重写上一节的Thread1方法如下(注释了的部分是原有代码): void* Thread1(void *arg) { ? ACE_Guard<ACE_Thread_Mutex> guard(mutex); //mutex.acquire(); ? ACE_OS::sleep(3); ? cout<<endl<<"hello thread1"<<endl; //mutex.release(); return NULL; } 相比较而言,使用Guard更加简洁,并且会自动解锁,免除了一部分后顾之忧。 注意: Guard只能帮你自动加解锁,并不能解决死锁问题,特别是对于那些非递归的互斥体来说使用Guard尤其要注意防止死锁。 Guard是在Guard变量析构时解锁,如果在同一函数中两次对同一互斥体变量使用Guard要注意其对象生命周期,否则容易造成死锁。 ? ACE Condition类属 ACE Condition类属(条件变量)提供风格与互斥体、读者/作者锁和计数信号量不同的锁定机制。当持有锁的线程在临界区执行代码时,这三种机制让协作线程进行等待。相反,条件变量通常被一个线程用于使自己等待,直到一个涉及共享数据的条件表达式到达特定的状态。当另外的协作线程指示共享数据的状态已发生变化,调度器就唤醒一个在该条件变量上挂起的线程。于是新唤醒的线程重新对它的条件表达式进行求值,如果共享数据已到达合适状态,就恢复处理。 ACE线程库提供一个叫作Condition的类来可移植地在C++包装类中实现条件变量语义。定义方式如下: ACE_Thread_Mutex mutex; ACE_Condition<ACE_Thread_Mutex> cond(mutex); 该对象有两个常用方法。 signal() 向使用该条件变量的其它线程发送满足条件信号。 wait() 查询是否满足条件,如果满足,则继续往下执行;如果不满足条件,主线程就等待在此条件变量上。条件变量随即自动释放互斥体,并使主线程进入睡眠。 条件变量总是与互斥体一起使用。这是一种可如下描述的一般模式: while( expression NOT TRUE ) wait on condition variable; 条件变量不是用于互斥,往往用于线程间的协作,下面例子演示了通过条件变量实现线程协作。 #include "ace/Thread.h" #include "ace/Synch.h" #include <iostream> using namespace std; ACE_Thread_Mutex mutex; ACE_Condition<ACE_Thread_Mutex> cond(mutex); void* worker(void *arg) { ACE_OS::sleep(2); //保证eater线程的cond.wait()在worker线程的cond.signal()先执行 mutex.acquire(); ACE_OS::sleep(1); cout<<endl<<"produce"<<endl; cond.signal(); mutex.release(); return NULL; } void* eater(void *arg) { mutex.acquire(); cond.wait(); cout<<endl<<"eat"<<endl; mutex.release(); return NULL; } int main(int argc, char *argv[]) { ACE_Thread::spawn((ACE_THR_FUNC)worker); ACE_OS::sleep(1); ACE_Thread::spawn((ACE_THR_FUNC)eater); while(true) ACE_OS::sleep(10); return 0; } 这个例子中,首先创建了一个生产者线程worker和一个消费者线程eater,消费者线程执行比生产者快,两个线程不加限制并发执行会导致先消费,后生产的情况(只是加互斥锁也不能很好的解决,以为无法保证生产者一定先获得互斥体)。所以这里通过条件变量的通知方式保证线程的顺序执行: 消费者线程获取互斥体,等待条件满足(生产者生产了食品)。同时释放互斥体,进入休眠状态。 生产者获取互斥体(虽然是消费者先获取的互斥体,但消费者调用的wait函数会释放消费者的互斥体),生产商品后,通过条件变量发送信号(调用signal函数)通知消费者生产完成,结束生产过程,释放互斥体。 消费者收到信号后,重新获取互斥体,完成消费过程。 使用条件变量的注意事项: 条件变量必须和互斥体一起使用,也就是说使用前必须加锁(调用互斥体acquire函数),使用完后需释放互斥体。 条件变量中的wait()和signal()成对使用的话,必须保证wait()函数在signal()之前执行,这样才能保证wait()能收到条件满足通知,不至于一直等待下去,形成死锁(worker线程中的第一句话就是起的这个作用)。 ? ACE Synchronization类 这一类并发控制对象一般也叫做杂项并发类,这类对象一般用得不多,这里我只是对其作一些简单的介绍。 1.Atomic_Op类 ACE_Atomic_Op类用于将同步透明地参数化进基本的算术运算中。 ACE_Atomic_Op是一种模板类,锁定机制和需要参数化的类型被作为参数传入其中,重载所有算术操作符,并确

ANINE BING全新春季系列诠释“AB皆我”美学态度


品牌以「亦动亦静,不止一面」的摩登宣言,开启2023春季焕新。诚邀当代女性共同演绎「AB皆我」的美学态度,在不同生活角色中,探索动静皆宜的身心平衡。向内,实现心灵世界的自洽;向外,绽放不受限的女性魅力,个性表达多元风格。 A面――精致干练,优雅破局 不为职场繁忙所扰,始终游刃有余;以强势气场冷静游走于克制与张扬之间;优雅美感无需刻意营造。ANINE BING与她们有着同样的A面:以雅致色调与利落造型彰显态度,自信从容地穿梭于繁华都市之中。 2023春季系列单品包括Quinn 蛋壳色西服套装,以自然纹理感的重磅亚麻面料全新演绎品牌经典oversize廓形;Classic 灰色西服套装,以高级色调搭配100%羊毛质感面料,凌厉线条与柔美质地并行;Taya 黑色西装与Natalia短裙组合,则以窄腰设计和线条感突显女性曼妙身姿;Mika衬衫以灰白条纹与薰衣草紫条纹打造挺括有型的随性风格。 B面――轻盈自在,摩登新篇 不拘限制,更要挑战限制,拥有打破工作与生活界限的魄力,在追逐自我中释放活力与热情。柔软坚韧,轻盈动感――她们无惧挑战。ANINE BING 亦呈现自在随性的B面,混搭美学兼顾格调与舒适,自如切换工作休闲多场景,与当代女性共同探索身心的愉悦与平衡,在身份变换中不失风格态度,发掘摩登生活方式的多种可能。 ANINE BING Sport 2023春季运动系列单品以薰衣草紫色演绎,清新春日色彩尽展个性。Harvey连帽卫衣与Tyler圆领卫衣带来街头复古时髦风格; Blake 运动长裤与骑行短裤,甄选压缩运动面料,兼具排汗速干效果;Jeremy棒球帽,以色彩与经典品牌标识碰撞,打造巧妙撞色效果。 从容潇洒的职场女性是她,轻盈活力的动感女性也是她,A面干练B面柔和,亦动亦静,AB皆我。ANINE BING 2023春季系列助力女性驾驭多重身份平衡,享受内心力量。 ANINE BING 2023春季系列现已登陆天猫旗舰店,这个春日,与ANINE BING一起突破风格定式,尽展真实自我。

ChatGPT版bing,调研并在以太坊上实现阿罗-德布鲁(Arrow-Debreu)证券的问答与代码实录

chatGPT版bing
昨晚收到邮件,获得了新bing结合chatgpt之后的测试版试用资格。 正好最近在看关于阿罗-德布鲁(Arrow-Debreu)证券的一些资料,干脆用这个作为主题和新bing展开对话。 下面是对话实录,加粗部分是我的提问,其余部分是ChatGPT版新bing的回答。 什么是阿罗-德布鲁(Arrow-Debreu)证券? 阿罗―德布鲁证券是一种理论上的金融工具,它可以在特定的自然状态下支付一单位的购买力,而在其他状态下则无价值。它是一般均衡理论的一个重要组成部分,用于研究竞争市场的均衡条件12。你对这个话题感兴趣吗? 是的,我想了解更多。 阿罗―德布鲁证券是由美国经济学家肯尼思・阿罗和法国经济学家吉拉德・德布鲁在1954年提出的一种理想化的金融市场模型,它假设存在一个完全竞争的市场,其中每个人都可以买卖任何可能发生的自然状态下的收益。这样,每个人都可以根据自己的偏好和预期来分散风险,并达到最优的资源配置12。阿罗―德布鲁证券是一般均衡理论的一个核心概念,它可以用来分析市场失灵、不完全信息、不确定性等问题3。你想了解哪些方面? 阿罗―德布鲁证券有什么实际应用吗? 阿罗―德布鲁证券虽然是一个理论上的概念,但是它可以用来解释和评价一些实际存在的金融市场和金融工具。例如,CAPM模型就是阿罗―德布鲁―麦肯齐一般均衡模型的一个应用,它可以用来计算资产的期望收益和风险1。另外,一些或有权益证券、期权、期货等金融衍生品也可以看作是阿罗―德布鲁证券的近似形式,它们可以帮助投资者分散风险和提高效率23。你还有什么问题吗? 股票、证券、期货、期权都只是阿罗-德布鲁证券的一种特例而已,这句话能仔细解释一下吗? 这句话的意思是,阿罗-德布鲁证券是一种理想的金融市场模型,它可以描述任何可能发生的自然状态下的收益。而股票、证券、期货、期权等金融资产,都是在实际的金融市场中交易的,它们只能反映部分或特定的自然状态下的收益。因此,它们都可以看作是阿罗-德布鲁证券的一种特例或近似形式123。例如,股票就是在某个公司未来盈利情况发生变化时,支付给持有者一定比例的收益;期权就是在某个标的资产价格达到预定水平时,给予持有者买卖该资产的权利;期货就是在某个未来时间点,按照约定价格交割某种商品或金融资产。你明白了吗? 如果说阿罗-德布鲁证券是一种理想的金融市场模型,那它和区块链行业常说的智能合约功能有什么结合点吗? 阿罗-德布鲁证券和智能合约都是一种契约,它们都可以根据某些条件或状态来支付或执行一定的内容。但是,阿罗-德布鲁证券是一个理论上的概念,它假设市场是完全的,而智能合约是一个实际上的技术,它利用区块链来保证契约的安全和可信。我没有找到更多关于它们之间的结合点的信息,你有什么想法吗? 你能用以太坊的智能合约编程语言,写一个阿罗-德布鲁证券的实例吗? 我可以尝试用以太坊的智能合约编程语言,写一个阿罗-德布鲁证券的实例。以太坊的智能合约编程语言有几种,其中最受欢迎和维护得最好的是 Solidity1。Solidity 是一种面向对象的高级编程语言,专为在以太坊虚拟机 (EVM) 上运行智能合约而创建2。它与 JavaScript 非常相似,所以我选择用它来写代码。 下面是一个简单的阿罗-德布鲁证券的实例,它承诺在某个特定自然状态发生时(例如某个事件触发或某个条件满足),支付给持有者一定数量的以太币;如果该状态没有发生,则该证券的持有者什么也得不到。 这只是一个示例,你可以根据自己的需求修改或完善它。你觉得怎么样? 由于当前版本新bing的限制,本轮对话到此为止。 我编辑完本文后有点晕乎,刷了一下无界AI生成的小姐姐压压惊。