Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

std::osyncstream outputs garbled text and causes seg fault

This code when using osyncstream outputs garbage characters, isn’t alway in sync, and seg faults. When output is to std::cout directly the output isn’t in sync but output is good and does not seg fault.

#include <atomic>
#include <chrono>
#include <iostream>
#include <syncstream>
#include <thread>

std::osyncstream sync_out { std::cout };
//std::ostream& sync_out { std::cout };

void test_ths(int th) {

    while(true) {
        sync_out << "th " << th << " wait 1\n";
//        std::this_thread::sleep_for(std::chrono::milliseconds(30 + 2 * th));
        std::this_thread::sleep_for(std::chrono::milliseconds(30));

        sync_out << "th " << th << " wait 2\n";
//        std::this_thread::sleep_for(std::chrono::milliseconds(30 + 2 * th));
        std::this_thread::sleep_for(std::chrono::milliseconds(30));

        // needed to force output from osyncstream
        sync_out.emit();  // comment out when using std::cout
    }
}
int main() {

    std::jthread t1([] {
        test_ths(1);
    });

    std::jthread t2([] {
        test_ths(2);
    });

    std::jthread t3([] {
        test_ths(3);
    });

    std::jthread t4([] {
        test_ths(4);
    });

    t1.join();
    t2.join();
    t3.join();
    t4.join();
}

Sample output illustrating problems.

th 2 wait 1
th th 4 wait 2
3 wait 2
th 1 wait 2
th 2 wait 2
th t 1
th о�ޓ�F�ߓ�F�@FfW��,@���W�th 4 wait 1
th  wait 1
th 2 wait 1
th 3 wait 2
th 4 wait 2
th 2 wait 2
th 3 wait 2
th 1 wait 2
th 2 wait 1
th 4 wait 1
th 3 wait 1
Segmentation fault (core dumped)

The problem is more pronounced when the sleep_for times are the same. The commented out lines introduce some jitter which helps but the problems still occur.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

When std::cout is used, with sync_out.emit(); commented out, it runs okay.

My understanding of osyncstream is the output from different thread shouldn’t intermingle, i.e. that is its purpose.

>Solution :

That’s not how osyncstream is supposed to be used. Every thread needs to construct its own osyncstream; there is no synchronization on access to the osyncstream itself. Only the transfer performed by emit is synchronized, and then only with respect to the streambuf it wraps.

Having a global osyncstream is therefore entirely pointless.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading