我有一个网络驱动器(Z:\),由多台Windows计算机共享.是否可以通过简单地在此网络驱动器上创建/删除文件来实现跨机器锁定?
例如,两台计算机A和B希望同时写入ID为123的共享资源.
其中一台计算机,比如A,首先通过创建一个空文件Z:\ locks\123来锁定资源.当B看到存在名为"123"的锁定文件时,B知道其他人正在使用资源123,所以它必须等待Z才能删除Z:\ locks\123才能访问资源.
这就像多线程中的关键部分,但我想在多台机器上完成它.
我正在尝试用Python实现.这是我想出的:
import os
import time
def lock_it(lock_id):
lock_path = "Z:\\locks\\" + lock_id
while os.path.exists(lock_path):
time.sleep(5) # wait for 5 seconds
# create the lock file
lock_file = open(lock_path, "w")
lock_file.close()
def unlock_it(lock_id):
# delete the lock file
lock_path = "Z:\\locks\\" + lock_id
if os.path.exists(lock_path):
os.remove(lock_path)
Run Code Online (Sandbox Code Playgroud)
这不起作用,因为可能有多个进程退出等待状态并同时创建锁定文件.
同样,问题是:是否可以在共享存储上实现跨机器锁定机制?
python synchronization locking distributed-computing multiprocessing
我想在Google App Engine数据存储区中保留一个大型有序列表(数百万个元素).需要快速插入.
最简单的方法是添加表示订单的索引属性(或列)"order_num".例如,列表[A,B,C]将像这样存储:
content order_num
--------------------
A 1
B 2
C 3
Run Code Online (Sandbox Code Playgroud)
但是,这并不能让您快速插入.例如,如果我想在A之后插入X,我必须将B和C重新编号为X的"腾出空间",即让B变为3,C变为4,X变为2.如果我这将是一场灾难拥有数百万个元素.
我在这里描述了一种称为"间隙方法"的可行解决方案.这种方法保持了相邻元素之间的差距.像这样:
content order_num
--------------------
A 1000
B 2000
C 3000
Run Code Online (Sandbox Code Playgroud)
当我想在A之后插入X时,我可以简单地添加X,其order_num设置为(1000 + 2000)/ 2 = 1500,不需要重新编号.
但随着这些差距变小,可能需要重新编号.我的问题是,是否有任何已知的重新编号策略?并决定差距的大小?
谢谢!
UPDATE
这里有更多细节.假设我在数据库中有一个元素列表,每个元素都有一个名为my_num的整数属性.my_num的值是任意正整数.假设我有一个列表[A,B,C,D],它们的my_num是
element my_num
---------------------
A 5
B 2
C 10
D 7
Run Code Online (Sandbox Code Playgroud)
现在,让我们定义一个accum()运算符:
accum(n) = element[0].my_num + element[1].my_num + ... + element[n-1].my_num
Run Code Online (Sandbox Code Playgroud)
所以每个元素的累加值都是
element my_num accum
----------------------------
A 5 5
B 2 7
C 10 17
D 7 24
Run Code Online (Sandbox Code Playgroud)
但是,累积值可能不应存储在数据库中,因为列表会不断更新.保持快速插入更好.
我想设计一个输入为整数x的查询:
query(x) = …
Run Code Online (Sandbox Code Playgroud) 默认情况下,boto会在将消息发送到SQS之前使用Base64对消息进行编码.示例代码:
conn = boto.connect_sqs('access_key_id', 'secret_key')
q = conn.get_queue('myqueue')
m = Message()
m.set_body('hello!')
q.write(m)
Run Code Online (Sandbox Code Playgroud)
通过将Raw()替换为RawMessage(),我可以将原始消息发送到队列而无需编码.但是如何在不解码的情况下从队列中读取消息?如果我使用以下代码:
rs = q.get_messages(1)
if rs:
m = rs[0]
print m.get_body()
Run Code Online (Sandbox Code Playgroud)
m.get_body()自动返回解码结果.有没有办法检索原始邮件?
谢谢!
Scrapy 的 JOBDIR 设置提供了可恢复的爬网,描述如下:
http://doc.scrapy.org/en/latest/topics/jobs.html
我尝试像这样执行我的抓取命令:
scrapy crawl myspider -o out.csv -t csv -s JOBDIR=./jobs/run-1
Run Code Online (Sandbox Code Playgroud)
当它仍在运行时,我通过按 CTRL-C 优雅地将其关闭。然后再次启动相同的命令以恢复它。我可以确认它正在从终端输出恢复抓取:
[myspider] INFO: Resuming crawl (74 requests scheduled)
Run Code Online (Sandbox Code Playgroud)
但是当我查看我的输出 CSV 文件时,我看到有这样的重复项:
name,email
Alice,alice@example.com
Bob,bob@example.com
...
name,email <- duplicated header!
Bob,bob@example.com <- duplicated row!
...
Run Code Online (Sandbox Code Playgroud)
这是正常的吗?我想知道是否可以在同一个命令中使用-o
option 和JOBDIR
。如果没有,我如何导出抓取的项目?
顺便说一句,我正在使用 Scrapy 0.22.1。
谢谢!
我想创建一个指向类方法的全局函数指针,所以我做了类似以下最小可重现示例的操作:
struct Foo<'a> {
data: &'a str,
}
impl<'a> Foo<'a> {
pub fn foo(&self) {
println!("{}", self.data);
}
}
type FooFn = fn(&Foo);
const FUNC: FooFn = Foo::foo;
fn main() {
let data = String::from("hello");
let foo = Foo { data: &data };
FUNC(&foo);
}
Run Code Online (Sandbox Code Playgroud)
但rustc
给了我这个错误:
$ rustc test.rs
error[E0308]: mismatched types
--> test.rs:13:21
|
13 | const FUNC: FooFn = Foo::foo;
| ^^^^^^^^ one type is more general than the other
|
= note: expected fn …
Run Code Online (Sandbox Code Playgroud)