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

314
Views
funcionamiento de semaforo en linux, recibo SIGSEGV y falla de segmentacion, que parte esta mal?

Mis funciones de hilo son:

 #include"stdio.h" #include"sys/types.h" #include"pthread.h" #include"semaphore.h" sem_t sem; int running = 1; int ret; void *pf(void *arg) //producer function { int semval; while(running) { sleep(1); sem_post(&sem); sem_getvalue(&sem,&semval); printf("produce : %d\n",semval); } } void *cf(void *arg) /*consumer function*/ { int semval; while(running) { sleep(1); sem_wait(&sem); sem_getvalue(&sem,&semval); printf("consume : %d\n",semval); } }

y la función principal es:

 int main() { pthread_t pf, cf; ret = sem_init(&sem,0,16); pthread_create(&pf,NULL,(void *)pf,NULL); /*create producer*/ pthread_create(&cf,NULL,(void *)cf,NULL); /*create consumer*/ sleep(1); running = 0; pthread_join(pf,NULL); pthread_join(cf,NULL); sem_destroy(&sem); return 0; }

Cuando ejecuto el archivo ejecutable, devuelve un error de segmentación. Creo que el programa puede acceder a una memoria no válida, ¡pero no sé qué parte de mi código está mal!

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

Ha nombrado las variables y funciones de su subproceso con el mismo nombre: pf y cf . Entonces las variables sombrean los nombres de las funciones. Nunca es una buena idea tener el mismo nombre para variables y funciones.

Cambio

 pthread_create(&pf,NULL,(void *)pf,NULL); /*create producer*/ pthread_create(&cf,NULL,(void *)cf,NULL); /*create consumer*/

para

 pthread_create(&pf,NULL,producer,NULL); /*create producer*/ pthread_create(&cf,NULL,consumer,NULL); /*create consumer*/

y cambie el nombre de sus funciones a producer y consumer respectivamente. Tenga en cuenta que el lanzamiento también es incorrecto (y no es necesario, incluso si lo lanza correctamente), que he eliminado.

Está devolviendo cualquier valor de las funciones de subproceso. Las funciones de subproceso deben devolver void * . Entonces necesita llamar a pthread_exit(NULL); o devolver un puntero nulo.

Otro problema importante es que está accediendo a la variable running sin ninguna sincronización, lo que conduce a la condición de carrera . Este es un comportamiento indefinido . Dependiendo de la programación del subproceso, si el subproceso main establece la running en 0 antes de que los subprocesos se ejecuten, es posible que sus subprocesos no ejecuten el ciclo while en absoluto.

over 4 years ago · Santiago Trujillo Report

0

pthread_t pf, cf; ret = sem_init(&sem,0,16); pthread_create(&pf,NULL,(void *)pf,NULL); /*create producer*/ pthread_create(&cf,NULL,(void *)cf,NULL); /*create consumer*/

en realidad está pasando los descriptores de hilo a pthread_create() como rutina de inicio. Tienen los mismos nombres que las funciones a las que parece referirse aquí, pero las sombrean. También tenga en cuenta que void * es un puntero a datos, que es incompatible con un puntero de función -> no convertir a void * aquí.

El código correcto sería, por ejemplo, así:

 pthread_t pt, ct; ret = sem_init(&sem,0,16); pthread_create(&pt,NULL,pf,NULL); /*create producer*/ pthread_create(&ct,NULL,cf,NULL); /*create consumer*/

Por cierto, sugerencia general: habilite las advertencias del compilador: gcc -Wall -Wextra le habría dicho qué está mal.

editar: siguiendo la discusión sobre la respuesta de Blue Moon : simplemente usar un int para cerrar sus hilos es realmente problemático. La carrera de datos que ocurre aquí no importa en la práctica la mayor parte del tiempo, porque normalmente, solo desea decirle a sus subprocesos que se detengan y no le importa cuándo sucede exactamente esto. Pero (y eso es un gran pero ): su compilador ve este código:

 while(running) { [...] }

donde la condición para while es el único acceso para running esta función. Sin saber acerca de la concurrencia, podría asumir legalmente que running , una vez leído, nunca cambia. Por lo tanto, leerlo una vez y usar este valor de lectura (por ejemplo, almacenado en un registro) para la condición de ciclo para siempre sería una optimización válida y definitivamente no es lo que desea.

Ah, y agregar un volatile a la running no es la solución, pero las explicaciones de esto tienden a ser largas, solo busque en Google.

Una posibilidad sería usar un semáforo para detener el hilo también. Por ejemplo, tengo esto en uno de mis proyectos subprocesos:

 /* check whether daemon shutdown was requested */ if (!sem_trywait(&forceExit)) { /* pass on to next thread */ sem_post(&forceExit); rcout = -2; break; }

El hilo principal solo hace un solo sem_post(&forceExit) para cerrar todos los demás hilos.

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!