Quels sont les langages de programmation les plus verts ? (Dr. Milan Milanović)

𝗖 𝗶𝘀 𝘁𝗵𝗲 𝗺𝗼𝘀𝘁 𝗲𝗳𝗳𝗶𝗰𝗶𝗲𝗻𝘁 𝗽𝗿𝗼𝗴𝗿𝗮𝗺𝗺𝗶𝗻𝗴 𝗹𝗮𝗻𝗴𝘂𝗮𝗴𝗲, 𝘄𝗵𝗶𝗹𝗲 𝗣𝘆𝘁𝗵𝗼𝗻 𝗮𝗻𝗱 𝗣𝗲𝗿𝗹 𝗮𝗿𝗲 𝘁𝗵𝗲 𝗹𝗲𝗮𝘀𝘁 𝗲𝗻𝘃𝗶𝗿𝗼𝗻𝗺𝗲𝗻𝘁𝗮𝗹 𝗳𝗿𝗶𝗲𝗻𝗱𝗹𝘆 𝗽𝗿𝗼𝗴𝗿𝗮𝗺𝗺𝗶𝗻𝗴 𝗹𝗮𝗻𝗴𝘂𝗮𝗴𝗲

Artcile complet : https://medium.com/codex/what-are-the-greenest-programming-languages-e738774b1957

Développement en C sous Linux : pthread et la fonction sleep().

Un petit exemple vaut mieux que de grands discours, voici le source en C :

#include 
#include 
#include 
#include <sys/time.h>
#include <sys/types.h>
#include 
static long debut = 0;
void* longue_pause(void* a){
        pid_t t = getpid();
        printf("pid = %d\n",(int)t);
        printf("thread longue_pause %d debut : %ld\n",(int)pthread_self(),time(0)-debut);
        sleep(10);
        printf("thread longue_pause %d fin : %ld\n",(int)pthread_self(),time(0)-debut);
}
void* petites_pauses(void* a){
	int i = 0;
        pid_t t = getpid();
        printf("pid = %d\n",t);
        printf("thread petites_pauses %d debut : %ld \n",(int)pthread_self(), time(0)-debut);
        for(; i < 10 ;++i){
                printf("thread petites_pauses %d en cours : %ld \n",(int)pthread_self(), time(0)-debut);
                sleep(1);
        }
}
int main(){
        pthread_t longue;
        pthread_t petit1;
        pthread_t petit2;
        debut = time(0);
        pthread_create(&longue,NULL,longue_pause,NULL);
        pthread_create(&petit1,NULL,petites_pauses,NULL);
        pthread_create(&petit2,NULL,petites_pauses,NULL);
	sleep(8);
	printf("Debut join: %ld\n",time(0)-debut);
        pthread_join(longue,NULL);
        printf("fin long : %ld\n",time(0)-debut); 
        pthread_join(petit1,NULL);
	printf("fin petit1 : %ld\n",time(0)-debut);	
        pthread_join(petit2,NULL);
	printf("fin petit2 : %ld\n",time(0)-debut);
}

Pour la compilation :

$ gcc test_pthread_test.c -lpthread -o test2

On lance le test :

$ ./test2 
pid = 324
thread longue_pause 1078445824 debut : 0
pid = 324
thread petites_pauses 1070053120 debut : 0 
thread petites_pauses 1070053120 en cours : 0 
pid = 324
thread petites_pauses 1061660416 debut : 0 
thread petites_pauses 1061660416 en cours : 0 
thread petites_pauses 1070053120 en cours : 1 
thread petites_pauses 1061660416 en cours : 1 
thread petites_pauses 1070053120 en cours : 2 
thread petites_pauses 1061660416 en cours : 2 
thread petites_pauses 1070053120 en cours : 3 
thread petites_pauses 1061660416 en cours : 3 
thread petites_pauses 1070053120 en cours : 4 
thread petites_pauses 1061660416 en cours : 4 
thread petites_pauses 1061660416 en cours : 5 
thread petites_pauses 1070053120 en cours : 5 
thread petites_pauses 1061660416 en cours : 6 
thread petites_pauses 1070053120 en cours : 6 
thread petites_pauses 1070053120 en cours : 7 
thread petites_pauses 1061660416 en cours : 7 
Debut join: 8
thread petites_pauses 1070053120 en cours : 8 
thread petites_pauses 1061660416 en cours : 8 
thread petites_pauses 1070053120 en cours : 9 
thread petites_pauses 1061660416 en cours : 9 
thread longue_pause 1078445824 fin : 10
fin long : 10
fin petit1 : 10
fin petit2 : 10

Le petit exemple nous montre bien qu’aucun sleep() ne fait une attente sur les autres pthreads, même celui dans le main().

J’ai pu voir sur des forums :

Effectivement sur le POSIX il est marqué : http://pubs.opengroup.org/onlinepubs/9699919799/functions/sleep.html :

The sleep() function shall cause the calling thread to be suspended from execution until either the number of realtime seconds specified by the argument seconds has elapsed or a signal is delivered to the calling thread and its action is to invoke a signal-catching function or to terminate the process.

Mais si beaucoup de personne se pose la question c’est que cela n’a pas toujours été le cas. Sauf problème de mémoire j’ai vu le changement entre la Redhat 8.0 et la Fédora 9.0.

Mes OS de développement ont été (dans l’ordre) :

  • Redhat 5.2 ( la seule version que j’ai acheté, misère – pour information la date de release est : 2 novembre 1998 ) : A l’université de Toulouse.
  • SuSE ? : Chez Centre Océanographique de Marseille.
  • Debian ? : Chez Cyber-workers / Alias .
  • Redhat ? : Chez Rightvision
  • Redhat 7.2 : Chez Honeywell / SeCOM
  • Redhat 8.0 : Chez Honeywell / SeCOM
  • Fédora 9.0 : Chez Honeywell / SeCOM
  • Fédora 14.0 : Chez Honeywell / SeCOM
  • Fédora 17.0 : Chez Honeywell / SeCOM
  • Oracle 7.0 : Chez Honeywell / SeCOM
  • Oracle 7.2 : Chez Honeywell / SeCOM
  • Oracle 7.3 : Chez Honeywell / SeCOM
  • Oracle 7.4 : Chez Honeywell / SeCOM
  • Oracle 7.5 & Fédora 26 sous Docker : Chez Honeywell / SeCOM
  • Ubuntu 16.04 :  Chez Honeywell / SeCOM

Chez moi c’est plutôt Raspbian STRETCH ( Débian )  : https://www.raspberrypi.org/downloads/raspbian/ .

Bref, cela fait seulement 20 ans que je suis sous Linux.

Ma version de Linux Ubuntu :

$ uname -a
Linux VirtualBox 4.15.0-36-generic #39~16.04.1-Ubuntu SMP Tue Sep 25 08:59:23 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

Au passage on peut aussi voir l’impact des directives de compilation sur la taille :

$ gcc test_pthread_test.c -lpthread -o test2
$ gcc test_pthread_test.c -lpthread -O2 -o test2-O2
$ gcc test_pthread_test.c -lpthread -O3 -o test2-O3
$ gcc test_pthread_test.c -lpthread -O -o test2-O
$ gcc test_pthread_test.c -lpthread -g -o test2-g
$ gcc test_pthread_test.c -lpthread -g -O3 -o test2-g-03
$ ls -l test2*
13208  test2
15024  test2-g
14880  test2-g-03
9120   test2-O
9120   test2-O2
9120   test2-O3

Voila.

(Bisous à Luc)

MYSQL : Portage de vieux code en C … misère.

Quelle misère ce portage sur une Fédora 14 :

# make
…
/usr/bin/ld: cannot find -lmysqlclient
 
# ldconfig -v | grep "mysql"
/usr/lib/mysql:
        libmysqlclient.so.16 -> libmysqlclient.so.16.0.0
        libmysqlclient_r.so.16 -> libmysqlclient_r.so.16.0.0
 
# rpm -qa | grep mysql
mysql-devel-5.1.58-1.fc14.i686
mysql-5.1.58-1.fc14.i686
mysql-libs-5.1.58-1.fc14.i686
 
# ld -lmysqlclient --verbose
GNU ld version 2.20.51.0.7-5.fc14 20100318
  Supported emulations:
   elf_i386
   i386linux
   elf_x86_64
   elf_l1om
using internal linker script:
==================================================
/* Script for -z combreloc: combine and sort reloc sections */
OUTPUT_FORMAT("elf32-i386", "elf32-i386",
              "elf32-i386")
OUTPUT_ARCH(i386)
ENTRY(_start)
SEARCH_DIR("/usr/i686-redhat-linux/lib"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib");
SECTIONS
{
  /* Read-only sections, merged into text segment: */
  PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x08048000)); . = SEGMENT_START("text-segment", 0x08048000) + SIZEOF_HEADERS;
  .interp         : { *(.interp) }
  .note.gnu.build-id : { *(.note.gnu.build-id) }
  .hash           : { *(.hash) }
  .gnu.hash       : { *(.gnu.hash) }
  .dynsym         : { *(.dynsym) }
  .dynstr         : { *(.dynstr) }
  .gnu.version    : { *(.gnu.version) }
  .gnu.version_d  : { *(.gnu.version_d) }
  .gnu.version_r  : { *(.gnu.version_r) }
  .rel.dyn        :
    {
      *(.rel.init)
      *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
      *(.rel.fini)
      *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
      *(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*)
      *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
      *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)
      *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)
      *(.rel.ctors)
      *(.rel.dtors)
      *(.rel.got)
      *(.rel.sharable_data .rel.sharable_data.* .rel.gnu.linkonce.shrd.*)
      *(.rel.sharable_bss .rel.sharable_bss.* .rel.gnu.linkonce.shrb.*)
      *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
      *(.rel.ifunc)
    }
  .rel.plt        :
    {
      *(.rel.plt)
      PROVIDE_HIDDEN (__rel_iplt_start = .);
      *(.rel.iplt)
      PROVIDE_HIDDEN (__rel_iplt_end = .);
    }
  .init           :
  {
    KEEP (*(.init))
  } =0x90909090
  .plt            : { *(.plt) *(.iplt) }
  .text           :
  {
    *(.text.unlikely .text.*_unlikely)
    *(.text .stub .text.* .gnu.linkonce.t.*)
    /* .gnu.warning sections are handled specially by elf32.em.  */
    *(.gnu.warning)
  } =0x90909090
  .fini           :
  {
    KEEP (*(.fini))
  } =0x90909090
  PROVIDE (__etext = .);
  PROVIDE (_etext = .);
  PROVIDE (etext = .);
  .rodata         : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
  .rodata1        : { *(.rodata1) }
  .eh_frame_hdr : { *(.eh_frame_hdr) }
  .eh_frame       : ONLY_IF_RO { KEEP (*(.eh_frame)) }
  .gcc_except_table   : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
  /* Adjust the address for the data segment.  We want to adjust up to
     the same address within the page on the next page up.  */
  . = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
  /* Exception handling  */
  .eh_frame       : ONLY_IF_RW { KEEP (*(.eh_frame)) }
  .gcc_except_table   : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
  /* Thread Local Storage sections  */
  .tdata          : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
  .tbss           : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
  .preinit_array     :
  {
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array))
    PROVIDE_HIDDEN (__preinit_array_end = .);
  }
  .init_array     :
  {
     PROVIDE_HIDDEN (__init_array_start = .);
     KEEP (*(SORT(.init_array.*)))
     KEEP (*(.init_array))
     PROVIDE_HIDDEN (__init_array_end = .);
  }
  .fini_array     :
  {
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(SORT(.fini_array.*)))
    KEEP (*(.fini_array))
    PROVIDE_HIDDEN (__fini_array_end = .);
  }
  .ctors          :
  {
    /* gcc uses crtbegin.o to find the start of
       the constructors, so we make sure it is
       first.  Because this is a wildcard, it
       doesn't matter if the user does not
       actually link against crtbegin.o; the
       linker won't look for a file to match a
       wildcard.  The wildcard also means that it
       doesn't matter which directory crtbegin.o
       is in.  */
    KEEP (*crtbegin.o(.ctors))
    KEEP (*crtbegin?.o(.ctors))
    /* We don't want to include the .ctor section from
       the crtend.o file until after the sorted ctors.
       The .ctor section from the crtend file contains the
       end of ctors marker and it must be last */
    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
    KEEP (*(SORT(.ctors.*)))
    KEEP (*(.ctors))
  }
  .dtors          :
  {
    KEEP (*crtbegin.o(.dtors))
    KEEP (*crtbegin?.o(.dtors))
    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
    KEEP (*(SORT(.dtors.*)))
    KEEP (*(.dtors))
  }
  .jcr            : { KEEP (*(.jcr)) }
  .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) }
  .dynamic        : { *(.dynamic) }
  .got            : { *(.got) *(.igot) }
  . = DATA_SEGMENT_RELRO_END (12, .);
  .got.plt        : { *(.got.plt)  *(.igot.plt) }
  .data           :
  {
    *(.data .data.* .gnu.linkonce.d.*)
    SORT(CONSTRUCTORS)
  }
  .data1          : { *(.data1) }
  /* Sharable data sections.  */
  .sharable_data   : ALIGN(CONSTANT (MAXPAGESIZE))
  {
    PROVIDE_HIDDEN (__sharable_data_start = .);
    *(.sharable_data .sharable_data.* .gnu.linkonce.shrd.*)
    /* Align here to ensure that the sharable data section ends at the
       page boundary.  */
    . = ALIGN(. != 0 ? CONSTANT (MAXPAGESIZE) : 1);
    PROVIDE_HIDDEN (__sharable_data_end = .);
  }
  _edata = .; PROVIDE (edata = .);
  __bss_start = .;
  .bss            :
  {
   *(.dynbss)
   *(.bss .bss.* .gnu.linkonce.b.*)
   *(COMMON)
   /* Align here to ensure that the .bss section occupies space up to
      _end.  Align after .bss to ensure correct alignment even if the
      .bss section disappears because there are no input sections.
      FIXME: Why do we need it? When there is no .bss section, we don't
      pad the .data section.  */
   . = ALIGN(. != 0 ? 32 / 8 : 1);
  }
  /* Sharable bss sections  */
  .sharable_bss   : ALIGN(CONSTANT (MAXPAGESIZE))
  {
    PROVIDE_HIDDEN (__sharable_bss_start = .);
    *(.dynsharablebss)
    *(.sharable_bss .sharable_bss.* .gnu.linkonce.shrb.*)
    *(SHARABLE_COMMON)
    /* Align here to ensure that the sharable bss section ends at the
       page boundary.  */
    . = ALIGN(. != 0 ? CONSTANT (MAXPAGESIZE) : 1);
    PROVIDE_HIDDEN (__sharable_bss_end = .);
  }
  . = ALIGN(32 / 8);
  . = ALIGN(32 / 8);
  _end = .; PROVIDE (end = .);
  . = DATA_SEGMENT_END (.);
  /* Stabs debugging sections.  */
  .stab          0 : { *(.stab) }
  .stabstr       0 : { *(.stabstr) }
  .stab.excl     0 : { *(.stab.excl) }
  .stab.exclstr  0 : { *(.stab.exclstr) }
  .stab.index    0 : { *(.stab.index) }
  .stab.indexstr 0 : { *(.stab.indexstr) }
  .comment       0 : { *(.comment) }
  /* DWARF debug sections.
     Symbols in the DWARF debugging sections are relative to the beginning
     of the section so we begin them at 0.  */
  /* DWARF 1 */
  .debug          0 : { *(.debug) }
  .line           0 : { *(.line) }
  /* GNU DWARF 1 extensions */
  .debug_srcinfo  0 : { *(.debug_srcinfo) }
  .debug_sfnames  0 : { *(.debug_sfnames) }
  /* DWARF 1.1 and DWARF 2 */
  .debug_aranges  0 : { *(.debug_aranges) }
  .debug_pubnames 0 : { *(.debug_pubnames) }
  /* DWARF 2 */
  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
  .debug_abbrev   0 : { *(.debug_abbrev) }
  .debug_line     0 : { *(.debug_line) }
  .debug_frame    0 : { *(.debug_frame) }
  .debug_str      0 : { *(.debug_str) }
  .debug_loc      0 : { *(.debug_loc) }
  .debug_macinfo  0 : { *(.debug_macinfo) }
  /* SGI/MIPS DWARF 2 extensions */
  .debug_weaknames 0 : { *(.debug_weaknames) }
  .debug_funcnames 0 : { *(.debug_funcnames) }
  .debug_typenames 0 : { *(.debug_typenames) }
  .debug_varnames  0 : { *(.debug_varnames) }
  /* DWARF 3 */
  .debug_pubtypes 0 : { *(.debug_pubtypes) }
  .debug_ranges   0 : { *(.debug_ranges) }
  .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
  /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
}
 
 
==================================================
attempt to open /usr/i686-redhat-linux/lib/libmysqlclient.so failed
attempt to open /usr/i686-redhat-linux/lib/libmysqlclient.a failed
attempt to open /usr/local/lib/libmysqlclient.so failed
attempt to open /usr/local/lib/libmysqlclient.a failed
attempt to open /lib/libmysqlclient.so failed
attempt to open /lib/libmysqlclient.a failed
attempt to open /usr/lib/libmysqlclient.so failed
attempt to open /usr/lib/libmysqlclient.a failed
 
# locate /libmysqlclient.so
/usr/lib/mysql/libmysqlclient.so
/usr/lib/mysql/libmysqlclient.so.16
/usr/lib/mysql/libmysqlclient.so.16.0.0
 
# ln -s /usr/lib/mysql/libmysqlclient.so /lib/libmysqlclient.so
 
# make
: undefined reference to `mysql_connect'
 

Ensuite il a fallu changer les fonctions mysql_connect par mysql_real_connect :

mysql_real_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd, const char *db, unsigned int port, const char *unix_socket, unsigned long client_flag);

Il faut retenir que le ‘ld’ permet de voir où doivent être les librairies.

Frédéric.