Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7598255
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 30, 20262026-05-30T22:21:45+00:00 2026-05-30T22:21:45+00:00

I have to small programs First // compile with -lpthread // TEST: // basename

  • 0

I have to small programs

First

// compile with -lpthread
// TEST:
// basename


#include <pthread.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <libgen.h>
#include <limits.h>
#include <inttypes.h>


// DATASET_LEN
#ifndef DATASET_LEN
#define DATASET_LEN 10000
#endif
// THREADS_NUM
#ifndef THREADS_NUM
#define THREADS_NUM 16
#endif


// need to call free(3) after
char** generateArray() {
    char** dataset = (char**)malloc(sizeof(char*) * DATASET_LEN);
    // fill dataset
    for (size_t i = 0; i < DATASET_LEN; ++i) {
        dataset[i] = (char*)malloc(sizeof(char) * CHAR_MAX);
        sprintf(dataset[i], "%i/%i/", rand(), rand());
    }

    return dataset;
}

// pthread_create(3) callback
void* run(void* args) {
    char** dataset = generateArray();
    char* baseName;

    for (size_t i = 0; i < DATASET_LEN; ++i) {
        baseName = basename(dataset[i]);
        printf("%s\n", baseName);

        free(dataset[i]);
    }

    free(dataset);
}

// main
int main(int argc, char** argv) {
    pthread_t* threads = (pthread_t*)malloc(sizeof(pthread_t) * THREADS_NUM);
    // threads start
    for (int i = 1; i <= THREADS_NUM; ++i) {
        pthread_create(&threads[i-1], NULL, run, NULL);
        fprintf(stderr, "Thread %u started\n", i);
    }
    // threads join
    for (int i = 1; i <= THREADS_NUM; ++i) {
        pthread_join(threads[i-1], NULL);
        fprintf(stderr, "Thread %u finished\n", i);
    }
    free(threads);

    return EXIT_SUCCESS;
}

Second:

// compile with -lpthread
// TEST:
// basename


#include <pthread.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <libgen.h>
#include <limits.h>
#include <inttypes.h>
#include <string>


// DATASET_LEN
#ifndef DATASET_LEN
#define DATASET_LEN 10000
#endif
// THREADS_NUM
#ifndef THREADS_NUM
#define THREADS_NUM 16
#endif


// need to call free(3) after
char** generateArray() {
    char** dataset = (char**)malloc(sizeof(char*) * DATASET_LEN);
    // fill dataset
    for (size_t i = 0; i < DATASET_LEN; ++i) {
        dataset[i] = (char*)malloc(sizeof(char) * CHAR_MAX);
        sprintf(dataset[i], "%i/%i/", rand(), rand());
    }

    return dataset;
}

// pthread_create(3) callback
void* run(void* args) {
    char** dataset = generateArray();
    char* baseName;
    std::string tmpStr;

    for (size_t i = 0; i < DATASET_LEN; ++i) {
        baseName = basename(dataset[i]);
        tmpStr = std::string(baseName);
        printf("%s\n", tmpStr.c_str());

        free(dataset[i]);
    }

    free(dataset);
}

// main
int main(int argc, char** argv) {
    pthread_t* threads = (pthread_t*)malloc(sizeof(pthread_t) * THREADS_NUM);
    // threads start
    for (int i = 1; i <= THREADS_NUM; ++i) {
        pthread_create(&threads[i-1], NULL, run, NULL);
        fprintf(stderr, "Thread %u started\n", i);
    }
    // threads join
    for (int i = 1; i <= THREADS_NUM; ++i) {
        pthread_join(threads[i-1], NULL);
        fprintf(stderr, "Thread %u finished\n", i);
    }
    free(threads);

    return EXIT_SUCCESS;
}

Both programs, works normal at linux, but on freebsd first(without std::string) not works
Can anybody explain why?

I see freebsd src at /usr/src/lib/libc/gen/basename.c and see a static var in function.
But because of it, with std::string program also must not works normal

By normal I mean, it output only numbers, and new lines

For tests I use:
./freebsd-threaded-basename | egrep -av '^[0-9\n\s]+$' | env LANG=c less

UPD I try to use strdup() or strcpy() result is the same – not normal
UPD *Every* time the version with std::string is run it works as expected

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-30T22:21:47+00:00Added an answer on May 30, 2026 at 10:21 pm

    The reason for your programs to behave unpredictably is basename, which is not thread-safe. basename is a little bit outdated. Modern C++ applications tend to use other means for parsing file path. Boost Filesystem Library is popular and may be used to do it.

    If you insist on using basename, place it to critical section together with some code which will get basename‘s result (be it printf, or strcpy, or some other). This guarantees that basename‘s result is not accessed from several threads simultaneously. Which means correct behavior.

    Now some guesswork about “why”. (Only guesswork, because it’s not possible to predict, how exactly non-threadsafe multithreaded program works).

    First version of your program performs basename loop partially in parallel (basename function and the loop itself), partially sequentially (printf and free are thread-safe functions, their implementation is protected by critical sections).

    Second version adds std::string, which means a lot more sequential code. It allocates memory for a new string, deallocates old memory (both these operations are thread-safe and protected by critical sections). Also (in some implementations) is uses atomic operations to update shared counter, and this decreases parallelism as well. All this actually transforms your program from parallel to fully sequential. All the threads are mostly waiting for some mutex. Or sometimes perform some complicated printf/memory/std::string computations. And very rarely one of the threads does relatively simple basename computations. Almost as if you added a critical section around basename.

    Possibly, correct results for Linux tests are because printf and free are enough to make the program almost sequential in this case. (Because something is done differently in Linux or because of different hardware).

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a small program I want to execute to test something #include <map>
I have been learning C++ in school to create small command-line programs. However, I
I have a small project that I need to compile. I have one header
I have a small program to order and sort email messages, outputting to a
I have a small program <350ish lines of code on 5 forms>. It works
i have a small program where an element is draged and dropped, when the
I have a small program to do in Java. I have a 2D array
I have a small server program that accepts connections on a TCP or local
I have a small Python program, which uses a Google Maps API secret key.
I currently have a small Java program which I would like to run both

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.