tomasfdel

SO Práctica 1

Apr 5th, 2018
318
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.65 KB | None | 0 0
  1. // EJERCICIO 1
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <unistd.h>
  5. #include <string.h>
  6. #include <sys/wait.h>
  7.  
  8. int main()
  9. {
  10.     int pip[2], i;
  11.     char linea[1024], *prog1, *prog2, *args1[10], *args2[10];
  12.     for(;;){
  13.         pipe(pip);
  14.         printf("Lo escucho, amo.\n");
  15.         fgets(linea, sizeof linea, stdin);
  16.         linea[strlen(linea)-1] = 0;
  17.         if (strcmp(linea, "fin") == 0)  break;
  18.        
  19.         prog1 = strtok(linea, "|");
  20.         prog2 = strtok(NULL, "|");
  21.         if(fork()==0){
  22.             close(pip[0]);
  23.             close(1);
  24.             dup(pip[1]);
  25.             close(pip[1]);
  26.             for(i = 0, args1[i] = strtok(prog1, " "); args1[i] != NULL; args1[++i] = strtok(NULL, " "));
  27.             args1[++i] = NULL;
  28.             execvp(args1[0], args1);
  29.             exit(-1);
  30.         }
  31.         wait(NULL);
  32.         if(fork()==0){
  33.             close(0);
  34.             dup(pip[0]);
  35.             close(pip[0]);
  36.             close(pip[1]);
  37.             for(i = 0, args2[i] = strtok(prog2, " "); args2[i] != NULL; args2[++i] = strtok(NULL, " "));
  38.             args2[++i] = NULL;
  39.             execvp(args2[0], args2);
  40.             exit(-1);
  41.         }
  42.         close(pip[0]);
  43.         close(pip[1]);
  44.         wait(NULL);
  45.     }
  46.     return 0;
  47. }
  48.  
  49.  
  50.  
  51.  
  52. // EJERCICIO 2
  53. #include <stdio.h>
  54. #include <pthread.h>
  55.  
  56. #define N_VISITANTES 1000000
  57.  
  58. volatile int visitantes = 0;
  59. pthread_mutex_t bloqueo = PTHREAD_MUTEX_INITIALIZER;
  60.  
  61. void *molinete(void *arg)
  62. {
  63.     int i;
  64.     for (i=0;i<N_VISITANTES;i++){
  65.         pthread_mutex_lock(&bloqueo);
  66.         visitantes++;
  67.         pthread_mutex_unlock(&bloqueo);
  68.     }
  69.   return NULL;
  70. }
  71.  
  72. int main()
  73. {
  74.     pthread_t m1, m2;
  75.     pthread_create(&m1, NULL, molinete, NULL);
  76.     pthread_create(&m2, NULL, molinete, NULL);
  77.     pthread_join(m1, NULL);
  78.     pthread_join(m2, NULL);
  79.  
  80.     printf("Hoy hubo %d visitantes!\n", visitantes);
  81.     return 0;
  82. }
  83.  
  84.  
  85. /*
  86. Apartado 1: La instrucción visitantes++ se divide en tres en assembler:
  87. una carga desde memoria, un incremento del valor y un almacenamiento en memoria.
  88. Es difícil conseguir un resultado de 2*N_VISITANTES pues pueden ocurrir
  89. cambios de contexto en algún punto entre dichas instrucciones, por lo que
  90. distintos resultados parciales del ciclo se irán sobreescribiendo entre sí.
  91.  
  92. Apartado 2: Al ejecutar con un N_VISITANTES bajo (10, por ejemplo), todos
  93. los resultados fueron correctos. Creemos que esto es porque un hilo completa
  94. su ejecución antes de que ocurra un cambio de contexto.
  95.  
  96. Apartado 3: El mínimo valor que podría imprimir el programa es 2. Teniendo
  97. dos hilos, A y B, las circunstancias serían las siguientes:
  98. - A carga el 0. Cambio de contexto.
  99. - B carga el 0. Cambio de contexto.
  100. - A se ejecuta hasta su penúltima iteración, escribiendo en memoria un N_VISITANTES - 1. Cambio de contexto.
  101. - B aumenta el 0 a un 1 y lo guarda en memoria. Cambio de contexto.
  102. - A carga el 1. Cambio de contexto.
  103. - B completa su ejecución, escribiendo N_VISITANTES en memoria.
  104. - A aumenta el 1 que había cargado y guarda 2 en memoria, completando su ejecución.
  105. */
  106.  
  107.  
  108.  
  109.  
  110. // EJERCICIO 3
  111. /*
  112. El deadlock puede ocurrir si todos los procesos toman consecutivamente el tenedor de su derecha. Entonces, todos van a estar esperando a que se libere el tenedor de su izquierda, pero nunca se liberarán ya que ningún hilo puede continuar.
  113. */
  114.  
  115.  
  116.  
  117. /*
  118. En este caso, dos filósofos competirán por agarrar el mismo tenedor, el que esté entre el comensal diestro y el zurdo. De esta forma, uno de ellos quedará esperando sin tener ningún tenedor en la mano, por lo que quedan cuatro filósofos entre los cuales distribuir los cinco tenedores. Así, se garantiza que al menos uno de ellos puede agarrar ambos tenedores.
  119. */
  120. #include <stdio.h>
  121. #include <unistd.h>
  122. #include <stdlib.h>
  123. #include <pthread.h>
  124.  
  125. #define N_FILOSOFOS 5
  126. #define ESPERA 5000000
  127.  
  128. pthread_mutex_t tenedor[N_FILOSOFOS];
  129.  
  130. void pensar(int i)
  131. {
  132.   printf("Filosofo %d pensando...\n",i);
  133.   usleep(random() % ESPERA);
  134. }
  135.  
  136. void comer(int i)
  137. {
  138.   printf("Filosofo %d comiendo...\n",i);
  139.   usleep(random() % ESPERA);
  140. }
  141.  
  142. void tomar_tenedores(int i)
  143. {
  144.   pthread_mutex_lock(&tenedor[i]); /* Toma el tenedor a su derecha */
  145.   pthread_mutex_lock(&tenedor[(i+1)%N_FILOSOFOS]); /* Toma el tenedor a su izquierda */
  146. }
  147.  
  148. void dejar_tenedores(int i)
  149. {
  150.   pthread_mutex_unlock(&tenedor[i]); /* Deja el tenedor de su derecha */
  151.   pthread_mutex_unlock(&tenedor[(i+1)%N_FILOSOFOS]); /* Deja el tenedor de su izquierda */
  152. }
  153.  
  154. void tomar_tenedores_zurdo(int i)
  155. {
  156.   pthread_mutex_lock(&tenedor[(i+1)%N_FILOSOFOS]); /* Toma el tenedor a su izquierda */
  157.   pthread_mutex_lock(&tenedor[i]); /* Toma el tenedor a su derecha */
  158. }
  159.  
  160. void dejar_tenedores_zurdo(int i)
  161. {
  162.   pthread_mutex_unlock(&tenedor[(i+1)%N_FILOSOFOS]); /* Deja el tenedor de su izquierda */
  163.   pthread_mutex_unlock(&tenedor[i]); /* Deja el tenedor de su derecha */
  164. }
  165.  
  166. void *filosofo(void *arg)
  167. {
  168.   int i = (int)arg;
  169.   for (;;)
  170.   {
  171.     if(i == 0){
  172.       tomar_tenedores_zurdo(i);
  173.       comer(i);
  174.       dejar_tenedores_zurdo(i);
  175.       pensar(i);
  176.     }else{
  177.       tomar_tenedores(i);
  178.       comer(i);
  179.       dejar_tenedores(i);
  180.       pensar(i);
  181.     }
  182.   }
  183. }
  184.  
  185. int main()
  186. {
  187.   int i;
  188.   pthread_t filo[N_FILOSOFOS];
  189.   for (i=0;i<N_FILOSOFOS;i++)
  190.     pthread_mutex_init(&tenedor[i], NULL);
  191.   for (i=0;i<N_FILOSOFOS;i++)
  192.     pthread_create(&filo[i], NULL, filosofo, (void *)i);
  193.   pthread_join(filo[0], NULL);
  194.   return 0;
  195. }
  196.  
  197.  
  198.  
  199. /*
  200. Si sólo se permite que N-1 filósofos tomen tenedores al mismo tiempo, por Principio del Palomar, uno de ellos puede tomar dos tenedores. De esta forma, se permite que al menos uno de ellos pueda comer en un momento dado, evitando un deadlock.
  201. */
  202. #include <stdio.h>
  203. #include <unistd.h>
  204. #include <stdlib.h>
  205. #include <pthread.h>
  206. #include <semaphore.h>
  207.  
  208. #define N_FILOSOFOS 5
  209. #define ESPERA 5000000
  210.  
  211. pthread_mutex_t tenedor[N_FILOSOFOS];
  212. sem_t semaforo;
  213.  
  214. void pensar(int i)
  215. {
  216.   printf("Filosofo %d pensando...\n",i);
  217.   usleep(random() % ESPERA);
  218. }
  219.  
  220. void comer(int i)
  221. {
  222.   printf("Filosofo %d comiendo...\n",i);
  223.   usleep(random() % ESPERA);
  224. }
  225.  
  226. void tomar_tenedores(int i)
  227. {
  228.   pthread_mutex_lock(&tenedor[i]); /* Toma el tenedor a su derecha */
  229.   pthread_mutex_lock(&tenedor[(i+1)%N_FILOSOFOS]); /* Toma el tenedor a su izquierda */
  230. }
  231.  
  232. void dejar_tenedores(int i)
  233. {
  234.   pthread_mutex_unlock(&tenedor[i]); /* Deja el tenedor de su derecha */
  235.   pthread_mutex_unlock(&tenedor[(i+1)%N_FILOSOFOS]); /* Deja el tenedor de su izquierda */
  236. }
  237.  
  238. void *filosofo(void *arg)
  239. {
  240.   int i = (int)arg;
  241.   for (;;)
  242.   {
  243.     sem_wait(&semaforo);
  244.     tomar_tenedores(i);
  245.     comer(i);
  246.     dejar_tenedores(i);
  247.     sem_post(&semaforo);
  248.     pensar(i);
  249.     }
  250. }
  251.  
  252. int main()
  253. {
  254.   int i;
  255.   pthread_t filo[N_FILOSOFOS];
  256.   sem_init(&semaforo, 0, N_FILOSOFOS - 1);
  257.   for (i=0;i<N_FILOSOFOS;i++)
  258.     pthread_mutex_init(&tenedor[i], NULL);
  259.   for (i=0;i<N_FILOSOFOS;i++)
  260.     pthread_create(&filo[i], NULL, filosofo, (void *)i);
  261.   pthread_join(filo[0], NULL);
  262.   sem_destroy(&semaforo);
  263.   return 0;
  264. }
  265.  
  266.  
  267.  
  268.  
  269. // EJERCICIO 4
  270. #include <stdio.h>
  271. #include <stdlib.h>
  272. #include <unistd.h>
  273. #include <pthread.h>
  274. #include <semaphore.h>
  275.  
  276. sem_t tabaco, papel, fosforos, otra_vez, fumadores[3];
  277.  
  278. void agente()
  279. {
  280.     for (;;) {
  281.         int caso = random() % 3;
  282.         sem_wait(&otra_vez);
  283.         switch (caso) {
  284.             case 0:
  285.                 sem_post(&fumadores[0]);
  286.                 sem_post(&tabaco);
  287.                 sem_post(&papel);
  288.                 break;
  289.             case 1:
  290.                 sem_post(&fumadores[1]);
  291.                 sem_post(&fosforos);
  292.                 sem_post(&tabaco);
  293.                 break;
  294.             case 2:
  295.                 sem_post(&fumadores[2]);
  296.                 sem_post(&papel);
  297.                 sem_post(&fosforos);
  298.                 break;
  299.         }
  300.     }
  301. }
  302.  
  303. void fumar(int fumador)
  304. {
  305.     printf("Fumador %d: Puf! Puf! Puf!\n", fumador);
  306.     sleep(1);
  307. }
  308.  
  309. void *fumador1(void *arg)
  310. {
  311.     for (;;) {
  312.         sem_wait(&fumadores[0]);
  313.         sem_wait(&tabaco);
  314.         sem_wait(&papel);
  315.         fumar(1);
  316.         sem_post(&otra_vez);
  317.     }
  318. }
  319.  
  320. void *fumador2(void *arg)
  321. {
  322.     for (;;) {
  323.         sem_wait(&fumadores[1]);
  324.         sem_wait(&fosforos);
  325.         sem_wait(&tabaco);
  326.         fumar(2);
  327.         sem_post(&otra_vez);
  328.     }
  329. }
  330.  
  331. void *fumador3(void *arg)
  332. {
  333.     for (;;) {
  334.         sem_wait(&fumadores[2]);
  335.         sem_wait(&papel);
  336.         sem_wait(&fosforos);
  337.         fumar(3);
  338.         sem_post(&otra_vez);
  339.     }
  340. }
  341.  
  342. int main()
  343. {
  344.     pthread_t s1, s2, s3;
  345.     sem_init(&tabaco, 0, 0);
  346.     sem_init(&papel, 0, 0);
  347.     sem_init(&fosforos, 0, 0);
  348.     sem_init(&fumadores[0], 0, 0);
  349.     sem_init(&fumadores[1], 0, 0);
  350.     sem_init(&fumadores[2], 0, 0);
  351.     sem_init(&otra_vez, 0, 1);
  352.    
  353.     pthread_create(&s1, NULL, fumador1, NULL);
  354.     pthread_create(&s2, NULL, fumador2, NULL);
  355.     pthread_create(&s3, NULL, fumador3, NULL);
  356.     agente();
  357.  
  358.     return 0;
  359. }
Add Comment
Please, Sign In to add comment