Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

476
Views
¿Por qué un programa C multiproceso se fuerza a una sola CPU en Mac OS X cuando system() se usa en un subproceso?

Encontré una extraña diferencia en el comportamiento de un programa que usa pthreads entre Linux y Mac OS X.

Considere el siguiente programa que se puede compilar con "gcc -pthread -o threadtest threadtest.c":

 #include <pthread.h> #include <stdio.h> #include <stdlib.h> static void *worker(void *t) { int i = *(int *)t; printf("Thread %d started\n", i); system("sleep 1"); printf("Thread %d ends\n", i); return (void *) 0; } int main() { #define N_WORKERS 4 pthread_t workers[N_WORKERS]; int args[N_WORKERS]; int i; for (i = 0; i < N_WORKERS; ++i) { args[i] = i; pthread_create(&workers[i], NULL, worker, args + i); } for (i = 0; i < N_WORKERS; ++i) { pthread_join(workers[i], NULL); } return 0; }

Ejecutar el ejecutable resultante en una máquina Mac OS X de 4 núcleos da como resultado el siguiente comportamiento:

 $ time ./threadtest Thread 0 started Thread 2 started Thread 1 started Thread 3 started Thread 0 ends Thread 1 ends Thread 2 ends Thread 3 ends real 0m4.030s user 0m0.006s sys 0m0.008s

Tenga en cuenta que la cantidad de núcleos reales probablemente ni siquiera sea relevante, ya que el tiempo simplemente se gasta en el comando de shell "dormir 1" sin ningún cálculo. También es evidente que los subprocesos se inician en paralelo ya que los mensajes "Subproceso... iniciado" aparecen inmediatamente después de que se inicia el programa.

Ejecutar el mismo programa de prueba en una máquina Linux da el resultado que espero:

 $ time ./threadtest Thread 0 started Thread 3 started Thread 1 started Thread 2 started Thread 1 ends Thread 2 ends Thread 0 ends Thread 3 ends real 0m1.010s user 0m0.008s sys 0m0.013s

Se inician cuatro procesos en paralelo, cada uno de los cuales duerme durante un segundo, y eso lleva aproximadamente un segundo.

Si pongo cálculos reales en la función de trabajador () y elimino la llamada del sistema (), veo la aceleración esperada también en Mac OS X.

Entonces, la pregunta es, ¿por qué el uso de la llamada system() en un subproceso serializa efectivamente la ejecución de los subprocesos en Mac OS X y cómo se puede prevenir?

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

@BasileStarynkevitch y @null señalaron que una implementación de mutex global en system() en la biblioteca C de Mac OS X podría ser responsable del comportamiento observado. @null proporcionó una referencia al archivo fuente potencial de la implementación system(), donde se encuentran estas operaciones:

 #if __DARWIN_UNIX03 pthread_mutex_lock(&__systemfn_mutex); #endif /* __DARWIN_UNIX03 */ #if __DARWIN_UNIX03 pthread_mutex_unlock(&__systemfn_mutex); #endif /* __DARWIN_UNIX03 */

Al desensamblar la función system() en lldb verifiqué que estas llamadas están realmente presentes en el código compilado.

La solución es reemplazar el uso de la función de biblioteca system() C con una combinación de las llamadas al sistema fork()/execve()/waitpid(). Una prueba de concepto rápida para la modificación de la función trabajador() en el ejemplo original:

 static void *worker(void *t) { static const char shell[] = "/bin/sh"; static const char * const args[] = { shell, "-c", "sleep 1", NULL }; static const char * const env[] = { NULL }; pid_t pid; int i = *(int *)t; printf("Thread %d started\n", i); pid = fork(); if (pid == 0) { execve(shell, (char **) args, (char **) env); } waitpid(pid, NULL, 0); printf("Thread %d ends\n", i); return (void *) 0; }

Con esta modificación, el programa de prueba ahora se ejecuta en aproximadamente un segundo en Mac OS X.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!