//manage 线程管理器 import win.guid; namespace thread; class manage { ctor( limit = 63 ){ this._guid = tostring(..win.guid.create()); var threads = {} }; getSlot = function(){ for(slot,thrd in threads) if(!thrd.handle ) return thrd; var len = #threads if( len >= limit) return this.waitOne(); var slot = len+1; threads[slot] = { _name = ..string.format("%s[%d]",this._guid, slot ) } return threads[slot] }; getHandles = function(){ var handles ={} for(slot,thrd in threads){ ..table.push( handles,thrd.handle ) //support push null } return handles; }; create = function( tfunc,...){ var thrd = this.getSlot(); if(!thrd) return {}; thrd.handle,thrd.id = ..thread.create( function(tfunc,name,...){ var ret = { tfunc(...) } ..thread.set(name, ret) },tfunc,thrd._name ,...); delay(1); return thrd; }; createLite = function( tfunc,...){ var thrd = this.getSlot(); if(!thrd) return {}; thrd.handle,thrd.id = ..thread.create(tfunc ,...); return thrd; }; createSuspended = function(...){ return ..thread.createSuspended(true,this.create,...) }; suspend = function(){ var handles = this.getHandles(); for(i,hdle in handles){ ..thread.suspend(hdle) } }; resume = function(){ var handles = this.getHandles(); for(i,hdle in handles){ ..thread.resume(hdle) } }; quitMessage = function(){ if( ! ..win[["quitMessage"]] ) error("使用 quitMessage() 函数之前请执行import win语句!",2) for(slot,thrd in threads){ if( thrd.handle ){ ..thread.resume( thrd.handle ) ::PostThreadMessage(thrd.id,0x12/*_WM_QUIT*/ ,0,0); ..raw.closehandle( thrd.handle ); } } threads = {}; //stop waiting }; busy = function(){ for(slot,thrd in threads){ if( thrd.handle ) return true; } }; waitOne = function(){ var handles = this.getHandles(); if(!#handles) return; var pos = ..thread.waitOne(handles) if(!pos){ this.quitMessage(); //return null; return; } var handle = handles[pos]; for(slot,thrd in threads){ if( thrd.handle == handle ){ ..raw.closehandle(handle); thrd.handle = null; thrd.id = null; if( thrd.onEnd ){ var result = ..thread.get( thrd._name ) if(result){ var _,ubound = ..table.range(result); thrd.onEnd( ..table.unpack(result,1,ubound ) ) ..thread.set( thrd._name,null ) //Remove } else { thrd.onEnd() } thrd.onEnd = null; } return thrd; } } return false; }; waitClose = function(){ this.resume(); while( this.waitOne() ) { } }; } namespace manage{ delay = ..win[["delay"]] : sleep } /**intellisense() thread.manage = 线程管理器 thread.manage() = 创建线程管理器。\n可使用一个参数指定线程池大小,\n默认为 63,该值必须小于 64\n!thread_mgr. ?thread.manage = !thread_mgr. !thread_mgr.create( = 创建线程,\n如果线程池已满会自动等待其他线程结束,并自动关闭已结束的线程句柄 !thread_mgr.create(.(线程执行函数,任意个启动参数) = 创建线程。\n此函数参数与 thread.create 函数的参数一致。\n\n返回对象可指定 onEnd 成员函数,\n线程结束将线程函数返回值作为参数回调 onEnd 函数。\n必须调用 thread.manage 对象的 waitClose 函数\n才会触发 onEnd 回调函数 !thread_mgr.createSuspended() = 创建线程并且暂停执行\n如果线程池已满会自动等待其他线程结束,并自动关闭已结束的线程句柄 !thread_mgr.createSuspended(.(线程执行函数,任意个启动参数) = 创建线程并且暂停执行。\n此函数参数与 thread.create 函数的参数一致。\n\n返回对象可指定 onEnd 成员函数,\n线程结束将线程函数返回值作为参数回调 onEnd 函数。\n必须调用 thread.manage 对象的 waitClose 函数\n才会触发 onEnd 回调函数 !thread_mgr.createLite( = 创建线程,但忽略线程执行函数的返回值。\n如果线程池已满会自动等待其他线程结束,并自动关闭已结束的线程句柄 !thread_mgr.createLite(.(线程执行函数,任意个启动参数) = 创建线程但忽略线程执行函数的返回值。\n此函数参数与 thread.create 函数的参数一致。\n\n返回对象可指定 onEnd 成员函数,\n线程函数结束将回调 onEnd 函数,回调函数无参数。\n必须调用 thread.manage 对象的 waitClose 函数\n才会触发 onEnd 回调函数 !thread_mgr.waitClose() = 等待所有线程返回,不阻塞界面线程消息处理。\n并关闭所有线程句柄。\n\n添加线程以后,必须调用 waitClose 函数 !thread_mgr.waitOne() = 等待任一线程返回,不阻塞界面线程消息处理。\n并关闭已结束的线程句柄。\n失败返回 null\n\nwaitClose 函数实际上循环调用 waitOne 函数。 !thread_mgr.suspend() = 所有线程暂停。\n注意线程是否正在使用互斥锁 !thread_mgr.resume() = 所有线程继续执行 !thread_mgr.busy() = 如果线程池里仍有未关闭的线程句柄返回 false,否则返回 true 。\n必须调用 waitOne 或 waitClose 函数才会自动关闭已结束的线程句柄 !thread_mgr.quitMessage() = 向所有线程发送 _WM_QUIT 消息\n线程内 win.delay 函数可接受该消息并返回 false 值 !thread_mgr.create() = !_thread_mgr_cb. !thread_mgr.createSuspended() = !_thread_mgr_cb. !thread_mgr.createLite() = !_thread_mgr_cbLite. !_thread_mgr_cb.onEnd = @.onEnd = function(...){ __/*线程结束回调此函数,参数为线程执行函数返回的值。\n必须调用 thread.manage 对象的 waitOne 或 waitClose 函数\n才会触发 onEnd 回调函数*/ } !_thread_mgr_cbLite.onEnd = @.onEnd = function(){ __/*线程结束回调此函数,无参数。\n必须调用 thread.manage 对象的 waitOne 或 waitClose 函数\n才会触发 onEnd 回调函数*/ } end intellisense**/