來源於:http://redisdoc.com/list/blpop.html#id1
BLPOP key [key …] timeout 可用版本: >= 2.0.0 時間復雜度: O(1) BLPOP 是列表的阻塞式(blocking)彈出原語。 它是 LPOP key 命令的阻塞版本,當給定列表內沒有任何元素可供彈出的時候,連接將被 BLPOP 命令阻塞,直到等待超時或發現可彈出元素為止。 當給定多個 key 參數時,按參數 key 的先后順序依次檢查各個列表,彈出第一個非空列表的頭元素。 非阻塞行為 當 BLPOP 被調用時,如果給定 key 內至少有一個非空列表,那么彈出遇到的第一個非空列表的頭元素,並和被彈出元素所屬的列表的名字一起,組成結果返回給調用者。 當存在多個給定 key 時, BLPOP 按給定 key 參數排列的先后順序,依次檢查各個列表。 假設現在有 job 、 command 和 request 三個列表,其中 job 不存在, command 和 request 都持有非空列表。考慮以下命令: BLPOP job command request 0 BLPOP 保證返回的元素來自 command ,因為它是按”查找 job -> 查找 command -> 查找 request “這樣的順序,第一個找到的非空列表。 redis> DEL job command request # 確保key都被刪除 (integer) 0 redis> LPUSH command "update system..." # 為command列表增加一個值 (integer) 1 redis> LPUSH request "visit page" # 為request列表增加一個值 (integer) 1 redis> BLPOP job command request 0 # job 列表為空,被跳過,緊接着 command 列表的第一個元素被彈出。 1) "command" # 彈出元素所屬的列表 2) "update system..." # 彈出元素所屬的值 阻塞行為 如果所有給定 key 都不存在或包含空列表,那么 BLPOP 命令將阻塞連接,直到等待超時,或有另一個客戶端對給定 key 的任意一個執行 LPUSH key value [value …] 或 RPUSH key value [value …] 命令為止。 超時參數 timeout 接受一個以秒為單位的數字作為值。超時參數設為 0 表示阻塞時間可以無限期延長(block indefinitely) 。 redis> EXISTS job # 確保兩個 key 都不存在 (integer) 0 redis> EXISTS command (integer) 0 redis> BLPOP job command 300 # 因為key一開始不存在,所以操作會被阻塞,直到另一客戶端對 job 或者 command 列表進行 PUSH 操作。 1) "job" # 這里被 push 的是 job 2) "do my home work" # 被彈出的值 (26.26s) # 等待的秒數 redis> BLPOP job command 5 # 等待超時的情況 (nil) (5.66s) # 等待的秒數 相同的key被多個客戶端同時阻塞 相同的 key 可以被多個客戶端同時阻塞。 不同的客戶端被放進一個隊列中,按『先阻塞先服務』(first-BLPOP,first-served)的順序為 key 執行 BLPOP 命令。 在MULTI/EXEC事務中的BLPOP BLPOP 可以用於流水線(pipline,批量地發送多個命令並讀入多個回復),但把它用在 MULTI / EXEC 塊當中沒有意義。因為這要求整個服務器被阻塞以保證塊執行時的原子性,該行為阻止了其他客戶端執行 LPUSH key value [value …] 或 RPUSH key value [value …] 命令。 因此,一個被包裹在 MULTI / EXEC 塊內的 BLPOP 命令,行為表現得就像 LPOP key 一樣,對空列表返回 nil ,對非空列表彈出列表元素,不進行任何阻塞操作。 # 對非空列表進行操作 redis> RPUSH job programming (integer) 1 redis> MULTI OK redis> BLPOP job 30 QUEUED redis> EXEC # 不阻塞,立即返回 1) 1) "job" 2) "programming" # 對空列表進行操作 redis> LLEN job # 空列表 (integer) 0 redis> MULTI OK redis> BLPOP job 30 QUEUED redis> EXEC # 不阻塞,立即返回 1) (nil) 返回值 如果列表為空,返回一個 nil 。 否則,返回一個含有兩個元素的列表,第一個元素是被彈出元素所屬的 key ,第二個元素是被彈出元素的值。 模式:事件提醒 有時候,為了等待一個新元素到達數據中,需要使用輪詢的方式對數據進行探查。 另一種更好的方式是,使用系統提供的阻塞原語,在新元素到達時立即進行處理,而新元素還沒到達時,就一直阻塞住,避免輪詢占用資源。 對於 Redis ,我們似乎需要一個阻塞版的 SPOP key 命令,但實際上,使用 BLPOP 或者 BRPOP key [key …] timeout 就能很好地解決這個問題。 使用元素的客戶端(消費者)可以執行類似以下的代碼: LOOP forever WHILE SPOP(key) returns elements ... process elements ... END BRPOP helper_key END 添加元素的客戶端(生產者)則執行以下代碼: MULTI SADD key element LPUSH helper_key x EXEC