我正在编写一个电报机器人,其中更多的线程处理每个异步更新。我对一个空字典进行硬编码,当机器人运行时,多个线程对其进行写入和读取。
最常见的操作是:
if key not in dict:
dict[key] = value
else:
dict[key].append(another_value)
Run Code Online (Sandbox Code Playgroud)
问题是,当一个线程检查 key 是否在 dict 中时,也许不是,另一个线程在其中写入了 key。
所以基本上我必须摆脱这种赛车状况。
我需要一个快速的解决方案。在网上搜索我找到了关于threading.Lock(). 这些答案大约有 10 年的历史。我想知道现在它是否仍然是一个很好的解决方案,或者也许还有一些新的图书馆
有一个像这样的清单
lst = ['hello', 'stack', 'overflow', 'friends']
Run Code Online (Sandbox Code Playgroud)
我该怎么做:
if there is not an element in lst starting with 'p=' return False else return True
Run Code Online (Sandbox Code Playgroud)
?
我在想的是:
for i in lst:
if i.startswith('p=')
return True
Run Code Online (Sandbox Code Playgroud)
但是我不能在循环中添加返回False或者它在第一个元素处出现.
我需要一个查询来更新表中的一行,但如果 id 不存在,它会插入默认值。它还必须避免线程竞争条件。
我在这里找到了一个应该没问题的答案 /sf/answers/554957021/
使用此查询:
UPDATE tbl x
SET tbl_id = 24
, name = 'New Gal'
FROM (SELECT tbl_id, name FROM tbl WHERE tbl_id = 4 FOR UPDATE) y
WHERE x.tbl_id = y.tbl_id
RETURNING y.tbl_id AS old_id, y.name AS old_name, x.tbl_id, x.name;
Run Code Online (Sandbox Code Playgroud)
所以我认为它应该在更新后返回旧值,并且应该防止线程竞争条件。
但是,如果该行不存在,我需要添加一个插入,并且这次还返回插入的值(旧值没有意义,因为它们不存在)。
所以基本上我需要做类似的事情
INSERT INTO tbl
(...) VALUES (...)
RETURNING ..., ...
ON CONFLICT DO
UPDATE tbl x
SET tbl_id = 24
, name = 'New Gal'
FROM (SELECT tbl_id, name FROM tbl WHERE tbl_id = …Run Code Online (Sandbox Code Playgroud) sql postgresql insert-update race-condition select-for-update
我有一个这样的元组
[
(379146591, 'it', 55, 1, 1, 'NON ENTRARE', 'NonEntrate', 55, 1),
(4746004, 'it', 28, 2, 2, 'NON ENTRARE', 'NonEntrate', 26, 2),
(4746004, 'it', 28, 2, 2, 'TheBestTroll Group', 'TheBestTrollGroup', 2, 3)
]
Run Code Online (Sandbox Code Playgroud)
我想代替这个:
[
(379146591, (('it', 55, 1, 1, 'NON ENTRARE', 'NonEntrate', 55, 1)),
(4746004, (('it', 28, 2, 2, 'NON ENTRARE', 'NonEntrate', 26, 2), ('it', 28, 2, 2, 'TheBestTroll Group', 'TheBestTrollGroup', 2, 3)))
]
Run Code Online (Sandbox Code Playgroud)
因此,对于任何元素,不是第一个元素的任何元素都在它的子元组之内,如果后一个元素与第一个元素具有相同的元素,它将被设置为前一个子元组的另一个子元组。
所以我可以做:
for i in data:
# getting the first element of the list
for …Run Code Online (Sandbox Code Playgroud)