Ημερήσια αρχεία: 29 Σεπτεμβρίου 2017


CentOS 7: C++: static linking cannot find -lstdc++ -lm and -lc

Recently, we were trying to compile a C++ application with the following compilation command on a CentOS 7 64bit :

g++ -static -O2 -lm -Wall -Wno-unused-result -std=c++11 -DCS_ACADEMY -DONLINE_JUDGE 510152025.cpp -o 510152025;

unfortunately, we got the following errors:

 /usr/bin/ld: cannot find -lstdc++
 /usr/bin/ld: cannot find -lm
 /usr/bin/ld: cannot find -lc
 collect2: error: ld returned 1 exit status

To resolve the issues, we performed the following installations to install the static versions of the glibc and libstdc libraries:

sudo yum install glibc-static libstdc++-static -y;

 

Advertisements

Fedora 26: C++: static linking cannot find -lstdc++ -lm and -lc

Recently, we were trying to compile a C++ application with the following compilation command on a Fedora 26 64bit :

g++ -static -O2 -lm -Wall -Wno-unused-result -std=c++14 -DCS_ACADEMY -DONLINE_JUDGE 510152025.cpp -o 510152025;

unfortunately, we got the following errors:

 /usr/bin/ld: cannot find -lstdc++
 /usr/bin/ld: cannot find -lm
 /usr/bin/ld: cannot find -lc
 collect2: error: ld returned 1 exit status

To resolve the issues, we performed the following installations to install the static versions of the glibc and libstdc libraries:

sudo dnf install glibc-static libstdc++-static -y;

 


C/C++: Get a random number that is in a specific range

Assuming you need to generate a random number that is in a specified range, you can do the following:

//int rand(void) creates a pseudo-random number in the range of 0 to RAND_MAX
//RAND_MAX is defined in stdlib.h and is the largest number rand will return (same as INT_MAX).
const int new_number = (rand() % (maximum_number + 1 - minimum_number)) + minimum_number;

The above code first creates a pseudo-random number that is in the range of [0, RAND_MAX].
Then it will divide it with the width (+1) of the range we want to use (maximum_number + 1 - minimum_number) and get the remainder (modulo).
The modulo will be in the range of [0, maximum_number - minimum_number], so we add to it the value of minimum_number to shift the result to the proper range.
This solution, as demonstrated in the example below, works for negative ranges as well.

Full example of generating 100000 random numbers that are all in the range [-31, 32].

const int maximum_number = 31;
const int minimum_number = -32;
unsigned int i;
for (i = 0; i <= 100000; i++) {
	const int new_number = (rand() % (maximum_number + 1 - minimum_number)) + minimum_number;
	printf("%d\n", new_number);
}

C/C++: Comparing the performance of syslog vs printf

The following code tries to compare the performance of syslog() with the printf() command. printf_vs_syslog.c (compressed) (273 downloads)
On our machine, it appears that syslog() is faster than printf().

To be as fair as possible, when the application was executing, we were monitoring the system logs as well, so that they will be printed on screen.
On CentOS 7, you can see the syslog in the file /var/log/messages.
The command we used was: sudo tail -f /var/log/messages

Results:

printf: Seconds elapsed 0.480000
syslog: Seconds elapsed 0.180000

Full source code for test:

printf_vs_syslog.c (compressed) (273 downloads)
#include <stdio.h>
#include <syslog.h>
// #include <stdlib.h> is needed for the resolution of EXIT_SUCCESS
#include <stdlib.h>
// #include <time.h> is needed for the clock() function and the macro CLOCKS_PER_SEC
#include <time.h>
// #include <unistd.h> and #include <sys/types.h> are needed for the functions uid_t getuid(void); and uid_t geteuid(void);
//getuid() returns the real user ID of the calling process.
//geteuid() returns the effective user ID of the calling process.
//These functions are always successful.
#include <unistd.h>
#include <sys/types.h>

#define RANGE (100000)

int main()
{
    {
        const clock_t start = clock();

        unsigned int i;
        for (i = 0; i < RANGE; i++){
            printf ("Program started by Real User %u (Effective User %u)\n", getuid(), geteuid());
        }
        printf("\n");

        const clock_t end = clock();
        const float seconds = (float) (end - start) / CLOCKS_PER_SEC;
        printf("printf: Seconds elapsed %f\n", seconds);
    }
    {
        const clock_t start = clock();

        setlogmask (LOG_UPTO (LOG_NOTICE));
        openlog ("bytefreaks", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);
        unsigned int i;
        for (i = 0; i < RANGE; i++){
            syslog (LOG_NOTICE, "Program started by Real User %u (Effective User %u)", getuid(), geteuid());
        }
        closelog ();

        const clock_t end = clock();
        const float seconds = (float) (end - start) / CLOCKS_PER_SEC;
        printf("syslog: Seconds elapsed %f\n", seconds);

    }
    return EXIT_SUCCESS;
}


printf_vs_syslog.c (compressed) (273 downloads)

C/C++: Set and Get the name of a pthread

Naming a pthread using meaningful names, can be a very useful feature for debugging multi-threaded applications as it can make your logs very informative.
For this reason, we are presenting two examples demonstrating the use of names in pthreads.

Example 1: The pthread decides for its name

The following code, creates a pthread which later, it will give itself a meaningful name.

pthread_self_named.c (compressed) (149 downloads)
// #define _GNU_SOURCE is needed for the resolution of the following warnings
//warning: implicit declaration of function ‘pthread_setname_np’ [-Wimplicit-function-declaration]
//warning: implicit declaration of function ‘pthread_getname_np’ [-Wimplicit-function-declaration]
#define _GNU_SOURCE
#include <stdio.h>
#include <sys/types.h>
#include <pthread.h>
#include <asm/errno.h>
#include <errno.h>
// #include <stdlib.h> is needed for the resolution of EXIT_SUCCESS
#include <stdlib.h>

//The thread name is a meaningful C language string, whose length is restricted to 16 characters, including the terminating null byte.
#define MAX_LENGTH_PTHREAD_NAME (16)

struct thread_info_t
{
    // Used to identify a thread.
    pthread_t thread_id;
};

// This is the thread that will be called by pthread_create() and it will be executed by the new thread.
void *self_named_thread(void *data)
{
    // We know that the input data pointer is pointing to a thread_info_t so we are casting it to the right type.
    struct thread_info_t *thread_info = (struct thread_info_t *) data;

    const int setname_rv = pthread_setname_np(thread_info->thread_id, "Tom Hanks");
    if (setname_rv)
    {
        errno = setname_rv;
        perror("Could not set pthread name");
    }

    char thread_name[MAX_LENGTH_PTHREAD_NAME];
    const int getname_rv = pthread_getname_np(thread_info->thread_id, thread_name, MAX_LENGTH_PTHREAD_NAME);
    if (getname_rv)
    {
        errno = getname_rv;
        perror("Could not get pthread name");
    }
    //This function always succeeds, returning the calling thread's ID.
    const pthread_t tid = pthread_self();
    //Usually pthread_t is defined as follows:
    //typedef unsigned long int pthread_t;
    //so we print pthread_t as an unsigned long int
    fprintf(stdout, "I am thread with ID '%lu', my name is '%s' and I gave me my name by myself\n", tid, thread_name );

    return NULL;
}

int main()
{
    struct thread_info_t thread_info;

    const int create_rv = pthread_create(&(thread_info.thread_id), NULL, &self_named_thread, (void *) &thread_info);
    if (create_rv)
    {
        errno = create_rv;
        perror("Could not create thread");
        return EXIT_FAILURE;
    }
    // The pthread_join() function suspends execution of the calling thread until the target thread terminates, unless the target thread has already terminated.
    const int join_rv = pthread_join(thread_info.thread_id, NULL);
    if (join_rv)
    {
        errno = create_rv;
        perror("Could not join thread");
    }
    return EXIT_SUCCESS;
}

pthread_self_named.c (compressed) (149 downloads)

Example 2: The parent decides for the pthread name

The next code, creates a pthread and the parent gives the thread a meaningful name.

pthread_named_by_parent.c (compressed) (134 downloads)
// #define _GNU_SOURCE is needed for the resolution of the following warnings
//warning: implicit declaration of function ‘pthread_setname_np’ [-Wimplicit-function-declaration]
//warning: implicit declaration of function ‘pthread_getname_np’ [-Wimplicit-function-declaration]
#define _GNU_SOURCE
#include <stdio.h>
#include <sys/types.h>
#include <pthread.h>
#include <asm/errno.h>
#include <errno.h>
// #include <stdlib.h> is needed for the resolution of EXIT_SUCCESS
#include <stdlib.h>
// #include <unistd.h> is needed for the resolution of unsigned int sleep(unsigned int seconds);
#include <unistd.h>

//The thread name is a meaningful C language string, whose length is restricted to 16 characters, including the terminating null byte.
#define MAX_LENGTH_PTHREAD_NAME (16)

struct thread_info_t
{
    // Used to identify a thread.
    pthread_t thread_id;
};

// This is the thread that will be called by pthread_create() and it will be executed by the new thread.
void *self_named_thread(void *data)
{
    // We know that the input data pointer is pointing to a thread_info_t so we are casting it to the right type.
    struct thread_info_t *thread_info = (struct thread_info_t *) data;

    //Added an artificial delay for the sake of the example.
    //Making sure the parent thread gave the pthread a name.
    sleep(1);

    char thread_name[MAX_LENGTH_PTHREAD_NAME];
    const int getname_rv = pthread_getname_np(thread_info->thread_id, thread_name, MAX_LENGTH_PTHREAD_NAME);
    if (getname_rv)
    {
        errno = getname_rv;
        perror("Could not get pthread name");
    }
    //This function always succeeds, returning the calling thread's ID.
    const pthread_t tid = pthread_self();
    //Usually pthread_t is defined as follows:
    //typedef unsigned long int pthread_t;
    //so we print pthread_t as an unsigned long int
    fprintf(stdout, "I am thread with ID '%lu', my name is '%s' and my parent gave me my name\n", tid, thread_name );

    return NULL;
}

int main()
{
    struct thread_info_t thread_info;

    const int create_rv = pthread_create(&(thread_info.thread_id), NULL, &self_named_thread, (void *) &thread_info);
    if (create_rv)
    {
        errno = create_rv;
        perror("Could not create thread");
        return EXIT_FAILURE;
    }

    const int setname_rv = pthread_setname_np(thread_info.thread_id, "Bob Marley");
    if (setname_rv)
    {
        errno = setname_rv;
        perror("Could not set pthread name");
    }

    // The pthread_join() function suspends execution of the calling thread until the target thread terminates, unless the target thread has already terminated.
    const int join_rv = pthread_join(thread_info.thread_id, NULL);
    if (join_rv)
    {
        errno = create_rv;
        perror("Could not join thread");
    }
    return EXIT_SUCCESS;
}

pthread_named_by_parent.c (compressed) (134 downloads)