Programacion: Threads en C

3GUGFVCXPCUB

De Wikipedia:

[code]]czo4NTA6XCJJbiBjb21wdXRlciBzY2llbmNlLCBhIHRocmVhZCBvZiBleGVjdXRpb24gaXMgdGhlIHNtYWxsZXN0IHVuaXQgb2YgcHJ7WyYqJl19b2Nlc3NpbmcgdGhhdCBjYW4gYmUgc2NoZWR1bGVkIGJ5IGFuIG9wZXJhdGluZyBzeXN0ZW0uIEl0IGdlbmVyYWxseSByZXN1bHRzIHtbJiomXX1mcm9tIGEgZm9yayBvZiBhIGNvbXB1dGVyIHByb2dyYW0gaW50byB0d28gb3IgbW9yZSBjb25jdXJyZW50bHkgcnVubmluZyB0YXNre1smKiZdfXMuIFRoZSBpbXBsZW1lbnRhdGlvbiBvZiB0aHJlYWRzIGFuZCBwcm9jZXNzZXMgZGlmZmVycyBmcm9tIG9uZSBvcGVyYXRpbmcgc3l7WyYqJl19c3RlbSB0byBhbm90aGVyLCBidXQgaW4gbW9zdCBjYXNlcywgYSB0aHJlYWQgaXMgY29udGFpbmVkIGluc2lkZSBhIHByb2Nlc3MuIHtbJiomXX1NdWx0aXBsZSB0aHJlYWRzIGNhbiBleGlzdCB3aXRoaW4gdGhlIHNhbWUgcHJvY2VzcyBhbmQgc2hhcmUgcmVzb3VyY2VzIHN1Y2gge1smKiZdfWFzIG1lbW9yeSwgd2hpbGUgZGlmZmVyZW50IHByb2Nlc3NlcyBkbyBub3Qgc2hhcmUgdGhlc2UgcmVzb3VyY2VzLiBJbiBwYXJ0aWN7WyYqJl19dWxhciwgdGhlIHRocmVhZHMgb2YgYSBwcm9jZXNzIHNoYXJlIHRoZSBsYXR0ZXJcJ3MgaW5zdHJ1Y3Rpb25zIChpdHMgY29kZSkgYW57WyYqJl19ZCBpdHMgY29udGV4dCAodGhlIHZhbHVlcyB0aGF0IGl0cyB2YXJpYWJsZXMgcmVmZXJlbmNlIGF0IGFueSBnaXZlbiBtb21lbnQpLntbJiomXX0gVG8gZ2l2ZSBhbiBhbmFsb2d5LCBtdWx0aXBsZSB0aHJlYWRzIGluIGEgcHJvY2VzcyBhcmUgbGlrZSBtdWx0aXBsZSBjb29rcyBye1smKiZdfWVhZGluZyBvZmYgdGhlIHNhbWUgY29vayBib29rIGFuZCBmb2xsb3dpbmcgaXRzIGluc3RydWN0aW9ucywgbm90IG5lY2Vzc2FyaWx7WyYqJl19eSBmcm9tIHRoZSBzYW1lIHBhZ2UuXCI7e1smKiZdfQ==[[/code]

En resumen

Un thread es un subproceso que corre en paralelo y que comparte la memoria y los recursos con su proceso padre (el proceso padre puede tener varios threads), esto nos permite resolver el problema de la ejecución lineal, y podemos lograr que por ejemplo 2 procesos modifiquen el valor de una misma variable (esto también se puede hacer usando forks u apuntadores :p).

A continuación ejemplifico en un código el rol de un productor y un consumidor, el productor genera Items y el consumidor los consume xD.

Funciona de la siguiente forma, cada thread apunta a una misma localidad de memoria donde va modificando los valores, pero en orden, ya que si no fuera así el valor actual podría ser modificado varias veces por un proceso (el consumidor podría consumir 2 veces seguidas o el productor producir 2 items seguidos).

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
/* Parameters to print_function.
*/

#define BUFFER_SIZE 10
//PRODUCTOS EN EXISTENCIA (memoria que compartiran los threads)
int j = 0; //in
//PRODUCTOS CONSUMIDOS (memoria que compartiran los threads)
int k = 0; //out

//TIPO DE DATO ITEM
typedef struct
{
  int dato;
}item;

//ARGUMENTOS DEL THREAD PRODUCTOR
struct propiedades_prod
{
  item buffer[BUFFER_SIZE];
  //numero de thread creado
  int n;
  int nextProduced;
};
//ARGUMENTOS DEL THREAD CONSUMIDOS
struct propiedades_cons
{
  item buffer[BUFFER_SIZE];
  int nextConsumed;
};

void* productor (void* parameters)
{
  struct propiedades_prod* p = (struct propiedades_prod*) parameters;

  int *creados;
  creados = &j;

  int *consumidos;
  consumidos = &k;
  
  while(1)
  {
    //while((*creados + 1) % BUFFER_SIZE == *consumidos) ;
    while((*creados + 1) == *consumidos) ;
    p->buffer[*creados].dato = p->nextProduced++;
    //printf("Productor: %d creo el producto: %d, %d %d \n",p->n,*creados,p->buffer[*creados].dato,*consumidos);
    printf("Productor: %d creo el producto: %d\n",p->n,*creados);
    *creados = (*creados + 1) % BUFFER_SIZE;
    //*creados = *creados + 1;    
    sleep(1);
  }
}
void* consumidor (void* parameters)
{ 
  struct propiedades_cons* p = (struct propiedades_cons*) parameters;

  int *creados;
  creados = &j;

  int *consumidos;
  consumidos = &k;
  
  while(1)
  {
    while(*creados == *consumidos) ;
    p->nextConsumed = p->buffer[*consumidos].dato;
    //printf("Consumio %d, %d %d \n",*consumidos,p->nextConsumed,*creados);
    printf("Consumio %d \n",*consumidos);
    *consumidos = (*consumidos + 1) % BUFFER_SIZE;
    //*consumidos = *consumidos + 1;    
    sleep(1);
  }
}
/* The main program.
*/
int main ()
{
  pthread_t thread1_id;//productores
  pthread_t thread2_id;//productores
  pthread_t thread3_id;//consumidor

  struct propiedades_prod thread1_prop;
  struct propiedades_prod thread2_prop;
  struct propiedades_cons thread3_prop;

  /* Creamos el 1 thread */
  thread1_prop.n = 1;
  thread1_prop.nextProduced = 0;
  pthread_create (&thread1_id, NULL, &productor, &thread1_prop);
  
  /* Creamos el 2 thread */
  thread2_prop.n = 2;
  thread2_prop.nextProduced = 0;
  pthread_create (&thread2_id, NULL, &productor, &thread2_prop);

  /* Creamos el 3 thread que sera el consumidor */
  thread3_prop.nextConsumed = 0;
  pthread_create (&thread3_id, NULL, &consumidor, &thread3_prop);

  pthread_join (thread1_id, NULL);
  pthread_join (thread2_id, NULL);
  pthread_join (thread3_id, NULL);
  return 0;
}

Para compilar el programa lo pueden guardar por ejemplo como thread.c y desde la shell de linux escriben:

gcc -lpthread thread.c -o thread

salu2

Si te gusto comparte ...Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedIn

3 pensamientos en “Programacion: Threads en C

  1. Alevsk
    Firefox 3.6.13 Ubuntu

    Claro, si los threads son muy interesantes jeje, nos sirven para resolver el problema de la ejecución en múltiples procesos, yo en Java también estoy aprendiendo pero casi no los se usar jeje, en C mas o menos si.

    salu2

    Responder

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *