【库】godking.lock 跨进程、跨线程,高性能读写锁

光庆 2月前 386

 演 示 效 果


import win.ui;
/*DSG{{*/
var winform = win.form(text="aardio form";right=272;bottom=203;topmost=1)
winform.add(
button={cls="button";text="无锁演示";left=27;top=132;right=120;bottom=184;z=2};
button2={cls="button";text="有锁演示";left=139;top=132;right=232;bottom=184;z=3};
edit={cls="edit";text="0";left=54;top=26;right=206;bottom=109;edge=1;font=LOGFONT(h=-16);multiline=1;z=1}
)
/*}}*/
 
import godking.lock;
import raw.struct;
var lock = godking.lock();
var data = ..raw.struct({int v});
winform.button.oncommand = function(id,event){
    winform.button.disabled = true;
    winform.button2.disabled = true;
    for(i=1;5;1){
        thread.invoke( 
            function(data){
                while(1){
                    import console;
                    console.dump("正在写=====");
                    thread.delay(1000);
                    data.v++;
                    console.dump("已写完");
                }
            },data
        )
    }
    thread.invoke( 
        function(data,winform){
                while(1){
                    thread.delay(200);
                    winform.edit.text = data.v;
                }
        },data,winform
    )
}
 
winform.button2.oncommand = function(id,event){
    winform.button.disabled = true;
    winform.button2.disabled = true;
    // 创建 5 个线程,申请【写】权限,进行数据写入。
    for(i=1;5;1){
        thread.invoke( 
            function(data,lock){
                import godking.lock;
                import console;
                lock = godking.lock(lock);
                
                while(1){
                    lock.write();
                        console.dump("--------------------【写】申请通过,数值 +1 ,每次只能有一个【写】申请通过。ID:"++ thread.getId());
                        thread.delay(1000);
                        data.v++;
                        console.dump("即将退出【写】操作");
                    lock.endWrite();
                }
            },data,lock
        )
    }
    // 创建 5 个线程,申请【读】权限,进行数据读取。
    for(i=1;5;1){
    	thread.invoke( 
        	function(data,winform,lock){
                	import godking.lock;
                	import console;
                	lock = godking.lock(lock);
                	while(1){
                    	lock.read();
                        	console.dump("--------------------【读】申请通过,有可能同时通过多个【读】申请。ID:" ++ thread.getId());        
                        	thread.delay(1000);
                        	winform.edit.text = data.v;
                        	console.dump("即将退出【读】操作");
                    	lock.endRead();
                	}
        	},data,winform,lock);
    }
    // 创建 1 个线程,不加锁,进行数据读取。
    thread.invoke( 
        function(data,winform){
                import console;
                while(1){
                    console.dump("无锁读,不受锁影响");
                    thread.delay(200);
                    winform.edit.text = data.v;
                }
        },data,winform);
}
 
winform.show();
win.loopMessage();
 速 度 测 试

不使用读写锁,5个线程同时写,速度如下:

使用读写锁,5个线程同一时间只能有1个写,速度如下:

在5个线程排队写入的情况下,性能下降不到一半,顶呱呱。

测试代码如下:

import win.ui;
/*DSG{{*/
var winform = win.form(text="aardio form";right=272;bottom=203;topmost=1)
winform.add(
button={cls="button";text="无锁演示";left=27;top=132;right=120;bottom=184;z=2};
button2={cls="button";text="有锁演示";left=139;top=132;right=232;bottom=184;z=3};
edit={cls="edit";text="0";left=54;top=26;right=206;bottom=72;edge=1;font=LOGFONT(h=-16);multiline=1;z=1};
edit2={cls="edit";text="0";left=54;top=80;right=206;bottom=126;edge=1;font=LOGFONT(h=-16);multiline=1;z=4}
)
/*}}*/

import godking.lock;
import raw.struct;
var lock = godking.lock();
var data = ..raw.struct({int v});

winform.button.oncommand = function(id,event){
    winform.button.disabled = true;
    winform.button2.disabled = true;
    for(i=1;5;1){
        thread.invoke( 
            function(data){
                while(1){
                    data.v++;
                }
            },data
        )
    }
    thread.invoke( 
        function(data,winform){
            	var tm = ..time.tick();
                while(1){
                    thread.delay(200);
                    winform.edit.text = data.v;
                    winform.edit2.text = math.floor(data.v/(time.tick()-tm)) + "次/ms"
                }
        },data,winform
    )
}
 
winform.button2.oncommand = function(id,event){
    winform.button.disabled = true;
    winform.button2.disabled = true;
    // 创建 5 个线程,【写】,进行数据写入。
    for(i=1;5;1){
        thread.invoke( 
            function(data,lock){
                import godking.lock;
                lock = godking.lock(lock);
                while(1){
                    lock.write();
                    data.v++;
                    lock.endWrite();
                }
            },data,lock
        )
    }
    // 创建 1 个线程,不加锁,进行数据读取。
    thread.invoke( 
        function(data,winform){
            	var tm = ..time.tick();
                while(1){
                    thread.delay(200);
                    winform.edit.text = data.v;
                    winform.edit2.text = math.floor(data.v/(time.tick()-tm)) + "次/ms"
                }
        },data,winform
    )
}
 
winform.show();
win.loopMessage();

 使用 thread.semaphore 实现差不多相同的效果。

 与 godking.lock 不同的是,semaphore 没有读、写之分,每次都只能允许一个。

import win.ui;
/*DSG{{*/
var winform = win.form(text="aardio form";right=272;bottom=203;topmost=1)
winform.add(
button2={cls="button";text="有锁演示";left=89;top=126;right=182;bottom=178;z=2};
edit={cls="edit";text="0";left=54;top=26;right=206;bottom=109;edge=1;font=LOGFONT(h=-16);multiline=1;z=1}
)
/*}}*/

import raw.struct;
var data = ..raw.struct({int v});

winform.button2.oncommand = function(id,event){
    winform.button2.disabled = true;
    // 创建 5 个线程,【写】,进行数据写入。
    for(i=1;5;1){
        thread.invoke( 
            function(data){
                import console;
                import thread.semaphore
                while(1){
	                var s = thread.semaphore("test",1);
                    s.waitOne();
                        console.dump("--------------------进入写,数值 +1 √√√√√√√√√√√√√√√√√√√√√√");
                        thread.delay(1000);
                        data.v++;
                        console.dump("即将退出【写】");
                    s.release();
                }
            },data
        )
    }
    // 创建 1 个线程,使用【读】,进行数据读取。
    thread.invoke( 
        function(data,winform,lock){
                import thread.semaphore;
                import console;
                while(1){
                    var s = thread.semaphore("test",1);
                    s.waitOne();
                        console.dump("--------------------进入读,数值是不会 +1 的。-------------");        
                        thread.delay(1000);
                        winform.edit.text = data.v;
                        console.dump("即将退出【读】");
                    s.release();
                }
        },data,winform,lock);    
    // 创建 1 个线程,不加锁,进行数据读取。
    thread.invoke( 
        function(data,winform){
                import console;
                while(1){
                    console.dump("无锁读,不受锁影响");
                    thread.delay(200);
                    winform.edit.text = data.v;
                }
        },data,winform);
}
 
winform.show();
win.loopMessage();


最新回复 (1)
  • Xmzzz 2月前
    0 2

    刚好用上,非常好用

返回