18

So I'm writing some multithreaded shit in C that is supposed to work cross-platform. MingW has Posix threads for Windows, so that saved already half of the platform dependency. The other half was that these threads need to run external programs.

Well, there's system(), right? Uhm yes, but it sucks. It's incredibly slow on Windows, and it looks like you can have only one system() call ongoing at the same time. Which kinda defeats the multithreaded driver. Ok, but there's CreateProcessA(), and that doesn't suck.

Fine, now for Linux. The fork/exec hack is quite ugly, but it works and is even fast. Just never use fork() without immediate exec(). First try under Cygwin... crap I fork bombed my system! What is this shit? Ah I fucked up the path names so that the external executable couldn't be run.

Lesson learnt: put an exit() right after the exec() in the path for child process. Should never be reached, but if it goes there, the exit() at least prevents a fork bomb.

Well yeah, sort of works under Cygwin, but only with up to 3 threads. Beyond that, it seems like fork() at some point gives two processes the same PID, and then shit hangs.

Even slapping a mutex around the fork and releasing it only in the parent process didn't help. Fork in Cygwin is like a fork in the ass. posix_spawn() should work better because it can be mapped more easily to the Windows model, but still no dice.

OK, testing under real Linux. Yeah, no issues with that one! But instead, I get some obscure "free(): invalid size" abort. What the fuck would that even mean?! Checking my free() calls: all fine.

Time to fire up GDB in the terminal! Put a catch on the abort signal, mh got just hex data. Shit I forgot to compile with -O0 and -g. Next try. Backtrace shows the full call trace, back to the originating line in my program - which is fclose() on a file.

Ahhh I remember! Under Linux, fclosing a file that is already closed makes the program crash. So probably I was closing it twice. Checking back.. yeah that's where it was.

Shit runs fast on several cores now!

Comments
  • 8
    So im writing some multithreaded shit in java.

    Thats it, thats all the story you get, figure the rest.
  • 3
    @tekashi after two hours, the build chain aborts with some strange error. Having fixed that, the program runs five times slower than what C/C++ would have allowed. You're happy because sales can upsell faster hardware. Also, you're finished faster so that you can browse shitty memes on devRant.
  • 1
    @hash-table yeah setjmp/longjmp are amazing. I've just never found an opportunity to use them right, i.e. in a way that makes the code clearer. But it's like a sword in my armoury reserved for dire times.
  • 1
    Alot of stuff at my work is C-only.

    For the larger software suits I put my foot down and enforced C++17.

    Still must be as close to the C-Core as possible, but man, you have no idea what a blessing <thread> and <atomic> are!

    Cross-platform multi-threading in pure C is no fun... 🤔
  • 1
    @Yamakuzure Uhm, C11 has threads and atomic, so that's no reason to go for C++.
  • 1
    @Fast-Nop Sure, but we are limited to C99. (C90 if the CTO could have his way)

    (Don't know if this is still correct, but last time I looked VC didn't fully support C11)
  • 1
    @Yamakuzure So you can push for a C++ standard from 2 years ago, but not for a C standard from 8 years ago because that would be too new? Strange CTO. ^^

    And yeah, the MS compiler is outdated with regard to C. But that's more an argument against CL than against C11.
  • 1
    @Fast-Nop Yeah, but part of our customers who'll run the software use Windows. 😭
    So I have two possibilities: VS with clang to support OpenMP 4.0, or C++17.

    The latter is feature complete, and the ui will be Qt 12 anyway.

    For software running on Linux only I am pushing slowly towards C++, but all library API headers I write must be C99 compatible.

    Strange, I know...
Add Comment