Red de conocimiento informático - Consumibles informáticos - Investigación cuantitativa sobre código fuente único

Investigación cuantitativa sobre código fuente único

En primer lugar, se trata de un problema entre productores y consumidores.

El productor es responsable de generar datos y luego colocarlos en el búfer buf mediante la operación put.

El consumidor es responsable de mostrar datos y leer datos de buf a través de la operación get.

========》

Veamos primero la función principal main()

El productor y el consumidor se implementan mediante dos subprocesos respectivamente. .

La función pthread_create() en la función principal se utiliza para crear estos dos hilos.

Se definen dos variables th_a y th_b para registrar los números de hilo de estos dos hilos.

Los cuerpos de programa del hilo son productores y consumidores respectivamente.

El siguiente pthread_join se utiliza para esperar a que finalicen los dos subprocesos. Porque si no espera, el hilo principal de la función principal finalizará inmediatamente y los dos subprocesos no habrán tenido tiempo de ejecutarse por completo.

=======》

Veamos los dos hilos de productor y consumidor respectivamente.

El productor realiza un bucle cien veces, colocando los datos en el búfer cada vez que llama a put, y finalmente coloca un OVER;

El consumidor realiza un bucle usando get para leer datos del búfer. e Imprimir hasta que se lean más bits de datos que datos.

========》

Veamos la operación de venta y la operación de obtención respectivamente.

Debido a que tanto put como get pueden acceder a buf, buf es un recurso clave. Para abordar este recurso crítico, buf debe bloquearse antes de usarlo.

pthread _ mutex _ lock(b- gt; función para bloquear el semáforo. Cada semáforo solo se puede bloquear una vez (lo que dije puede no ser exacto). Si el semáforo en el parámetro ha estado bloqueado , la función se bloqueará hasta que se desbloquee el semáforo. Esto garantiza que se pueda acceder a los recursos críticos protegidos por el semáforo a través del mutex? >int? BUFFER[BUFFER_SIZE];/*?Este es un búfer circular*/? >

pthread_mutex_t? Lock;/*Este es un semáforo que garantiza la exclusión mutua del acceso al búfer*/ ?

int? writepos/*?Estos dos miembros representan la posición de lectura y la posición de escritura. respectivamente?

notempty/*?Este es un semáforo condicional, lo que indica que el búfer "no está vacío"?

pthread_cond_t?/*?Este es un semáforo condicional, lo que indica que el búfer no está lleno.

};?

Buf es un búfer circular. Veamos primero las posiciones de readpos y writepos cuando el búfer está vacío.

Al cambiar de completo a completo, la siguiente posición de writepos es readpos?

/*?Put es responsable de colocar los datos en el búfer*/. p>¿Invalidar? put(struct? prodcons? *? b, ? int? data)?

{?

//Bloquear el mutex primero

pthread_mutex_lockb-gt; bloquear);?

/*?Aquí se determina si el búfer está lleno y se compara usando writepos 1 y readpos. Consulte la imagen adjunta.

*?Debido a que es un buffer circular, necesitamos tomar el módulo BUFFER_SIZE? .

*?Si el búfer está lleno, esperará un momento hasta que el búfer no esté lleno y luego continuará la ejecución.

*/?

¿Cuándo? ((b- gt; writepos? ?1)??BUFFER_SIZE?==?b- gt; readpos)? {?

printf("¿Esperar? ¿Para qué? ¿No? Completo\n ");?

//Si está lleno, espere a que el consumidor lea los datos y envíe una señal de "no lleno".

pthread_cond_wait(amp;b-gt;no lleno,?ampb-gt;lock);?

}?

/*?Cuando el búfer no está lleno, escribe datos en la ubicación correspondiente a writepos en el búfer*/?

b-gt; buffer; escribirpos]? =?datos;?

//Actualiza writepos a la siguiente posición.

b- gt; escribir pos;?

//Reciclar espacio en el buffer. Si se excede el valor máximo, comience desde el principio.

¿Y si? (b->writepos?gt=?BUFFER_SIZE)? b-gt;writepos? =?0;?

/*?¿Señalar a los consumidores que el buffer no está vacío? */?

pthread_cond_signal(amp;b-gt;notempty);?

//Desbloquear la señal mutex.

pthread_mutex_unlock(&b-gt;bloquear);?

}?

/* - */?

/*?Get es responsable de leer los datos del buffer? */?

int? get(estructura?prodcons?*?b)?

{?

int? datos;?

//Bloquear el semáforo mutex

pthread_mutex_lockb- gt;?

/*? Determine si el búfer está vacío. Si está vacío, espere */?.

¿Cuándo? (b->escribirpos?==?b->readpos)? {?

printf("¿Esperar? ¿Para qué? ¿No? vacío \ n ");?

pthread_cond_wait(&b-gt;notempty,?ampb-gt;lock);?

}?

/*?¿Leer los datos en la posición readpos? */?

¿Datos? =?b- gt;búfer;leer pos];?

//Actualiza readpos a la siguiente posición.

b- gt;leer pos;?

//Recicle el búfer y vuelva a llamar el puntero.

¿Y si? (b->readpos? gt=?BUFFER_SIZE)? b-gt;readpos? =?0;?

/*?Notifique al productor que el búfer no está lleno y que los datos pueden liberarse*/?

pthread_cond_signal(amp;b-gt;no lleno);?

//Desbloquear el semáforo mutex

pthread _ mutex _ unlock(amp; b- gt; lock);?

¿Volver? datos;?

}