For example, I have tried this toy dataset:
import numpy as np
import torch
import time


class ToyDataset(torch.utils.data.IterableDataset):
    def __init__(self, numworkers):
        super().__init__()
        self.numworkers = numworkers
        self.batchidx = 0
    
    
    def __iter__(self):
        return self
    
    
    def __next__(self):
        id = 0
        info = torch.utils.data.get_worker_info()
        if info is not None:
            id = info.id
        
        if id < self.numworkers - 1:
            time.sleep(0.5)
            print('fast worker {:d}, batch {:d}'.format(id, self.batchidx))
        else:
            time.sleep(5)
            print('-slow worker {:d}, batch {:d}'.format(id, self.batchidx))
        
        
        retval = self.batchidx
        self.batchidx += 1
        return retval


BATCH_SIZE = 1
NUM_WORKERS = 2
TIMEOUT = 0
PREFETCH_FACTOR = 2


dataset = ToyDataset(NUM_WORKERS)
dataloader = torch.utils.data.DataLoader(
    dataset, 
    batch_size = BATCH_SIZE, 
    num_workers = NUM_WORKERS, 
    timeout = TIMEOUT, 
    prefetch_factor = PREFETCH_FACTOR)
it = iter(dataloader)

for i in range(1000):
    try:
        data = next(it)
        print('----------')
    except RuntimeError:
        print('timeout')


The output is something like this:
fast worker 0, batch 5
-slow worker 1, batch 3


fast worker 0, batch 6
-slow worker 1, batch 4


fast worker 0, batch 7
-slow worker 1, batch 5

The data generation is always slowed down by the slow worker.