Factorize All Numbers Up to a Given Number
Timing
The timer thread is unnecessary and an inaccurate way to measure time.

I do now know about this system_clock, system calls might slow down the process (maybe the context switch even more though)

Querying the time costs a bit of time, even if it does not involve an actual system call - which it really may not, there are lots of clever tricks for example clock_gettime uses vDSO on modern Linux and reads from a shared memory location and QueryPerformanceCounter reads the TSC on typical Windows systems, there is no transition into and out of kernel mode. It's never a lot of time relative to what this program is doing, the overhead of getting the time is only an issue when timing very short spans of time. Even if getting the time costs a milisecond (which would be unacceptable and considered a bug in the implementation), it would still be OK for this program.
Performance
Storing the factors in explicit linked lists is a major performance problem, and unlike usual, using vectors wouldn't be great either. There is an alternative: store only one factor of a number. That still gives a complete factorization for any number, because if a number N has a factor factors[N], then you can divide N by that factor and look up a factor of the new (smaller) number and so on, until 1 is reached.
That way the inner loop of the sieve only does a bunch of stores into a vector, nothing heavy-weight like dynamically allocating nodes of a linked list, and the memory usage does not get out hand.
As a convention, I'll use that the lowest factor of a prime is the prime itself. That is the mathematical definition, and it makes iterating over the implicit factor lists easy.
Other
Defining MAX by macro definition and putting local variable declarations at the top of the function are very C things to do. Even C has moved away from &quot;all locals at the top&quot;. As general guidelines, I recommend using const variables instead of defines, and limiting local variables with the smallest possible scope. That does not repeatedly incur a cost for &quot;making a variable&quot; because that's not how that happens, any fixed space a function needs is allocated all at once at function entry. Besides, most local variables spend their entire lifetime in registers.
Avoid #include &lt;unistd.h&gt; if possible/reasonable, it does not exist on all platforms.
Pick a brace style and stick to it. There were &quot;same line&quot;-braces and &quot;next line&quot;-braces. There are various opinions on which should be used, but at least they shouldn't be mixed.
In total, the code might come out like this:
#include &lt;iostream&gt;
#include &lt;vector&gt;
#include &lt;math.h&gt;
#include &lt;chrono&gt;

int main() {
    const int MAX = 200000000;
    std::vector&lt;int&gt; factors;

    std::cout &lt;&lt; &quot;Initiallizating&quot; &lt;&lt; std::endl;
    auto start_time = std::chrono::steady_clock::now();
    factors.resize(MAX);
    std::cout &lt;&lt; &quot;Initiallization took &quot;
        &lt;&lt; std::chrono::duration_cast&lt;std::chrono::milliseconds&gt;(std::chrono::steady_clock::now() - start_time).count()
        &lt;&lt; &quot; ms&quot; &lt;&lt; std::endl;

    std::cout &lt;&lt; &quot;Starting calculation&quot; &lt;&lt; std::endl;
    start_time = std::chrono::steady_clock::now();
    int upper_bound = sqrt(MAX) + 1;
    for (int i = 2; i &lt; upper_bound; ++i) {
        if (factors[i] == 0) {
            for (int j = i; j &lt; MAX; j += i) {
                factors[j] = i;
            }
        }
    }
    std::cout &lt;&lt; &quot;Calculation took &quot;
        &lt;&lt; std::chrono::duration_cast&lt;std::chrono::milliseconds&gt;(std::chrono::steady_clock::now() - start_time).count()
        &lt;&lt; &quot; ms&quot; &lt;&lt; std::endl;

    std::cout &lt;&lt; &quot;Validating results&quot; &lt;&lt; std::endl;
    for (int i = 2; i &lt; 20; ++i) {
        std::cout &lt;&lt; i &lt;&lt; &quot;: &quot;;
        if (factors[i] == i) {
            std::cout &lt;&lt; &quot;Is prime&quot;;
        }
        else {
            for (int N = i; N &gt; 1; N /= factors[N]) {
                std::cout &lt;&lt; factors[N] &lt;&lt; &quot;, &quot;;
            }
        }
        std::cout &lt;&lt; std::endl;
    }

    return 0;
}

On my PC the sieving takes about 2.5 seconds now. Ideone is a bit slower but the program is fast enough to run there too.