<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://so.v2.cs.unibo.it/wiki/index.php?action=history&amp;feed=atom&amp;title=Buffer_Limitato</id>
	<title>Buffer Limitato - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://so.v2.cs.unibo.it/wiki/index.php?action=history&amp;feed=atom&amp;title=Buffer_Limitato"/>
	<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Buffer_Limitato&amp;action=history"/>
	<updated>2026-05-12T10:50:21Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.35.5</generator>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Buffer_Limitato&amp;diff=1093&amp;oldid=prev</id>
		<title>MV: Created page with &quot;&lt;source lang=&quot;text&quot;&gt; Esercizio di programmazione concorrente: Il programma genera 2 thread. Il primo di questi, detto producer, prende i valori da stdin e li scrive su un buff...&quot;</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Buffer_Limitato&amp;diff=1093&amp;oldid=prev"/>
		<updated>2015-05-12T20:33:27Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt; Esercizio di programmazione concorrente: Il programma genera 2 thread. Il primo di questi, detto producer, prende i valori da stdin e li scrive su un buff...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Esercizio di programmazione concorrente:&lt;br /&gt;
Il programma genera 2 thread.&lt;br /&gt;
Il primo di questi, detto producer, prende i valori da stdin e li scrive su un buffer.&lt;br /&gt;
Il secondo, detto consumer, legge i valori dal buffer e li scrive su un file.&lt;br /&gt;
Requisiti:&lt;br /&gt;
- Il buffer è usato come array circolare&lt;br /&gt;
- Producer non deve scrivere su valori non ancora letti&lt;br /&gt;
- Consumer deve leggere i valori in ordine e senza ripetizioni&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Soluzione di MV, usando i semafori ==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;errno.h&amp;gt;&lt;br /&gt;
#include &amp;lt;pthread.h&amp;gt;&lt;br /&gt;
#include &amp;lt;semaphore.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/stat.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define DIM_BUF 10&lt;br /&gt;
#define THREAD_SHARED 0&lt;br /&gt;
&lt;br /&gt;
char buffer[DIM_BUF];&lt;br /&gt;
int next_write = 0, next_read = 0;	// indici sul buffer&lt;br /&gt;
sem_t empty;	// semaforo: consumer si blocca su di esso quando il buffer è vuoto&lt;br /&gt;
sem_t full;		// semaforo: producer si blocca su di esso quando il buffer è pieno&lt;br /&gt;
&lt;br /&gt;
void* producer_routine(void *arg)&lt;br /&gt;
{&lt;br /&gt;
	char c;&lt;br /&gt;
	while(scanf(&amp;quot;%c&amp;quot;,&amp;amp;c) != EOF)	// legge (&amp;quot;produce&amp;quot;) un carattere da stdin&lt;br /&gt;
	{&lt;br /&gt;
		if(sem_wait(&amp;amp;full) != 0)	// si blocca se il buffer è pieno&lt;br /&gt;
		{&lt;br /&gt;
			printf(&amp;quot;Error %i in producer: %s&amp;quot;,errno,strerror(errno));&lt;br /&gt;
			break;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		buffer[next_write] = c;&lt;br /&gt;
		next_write = (next_write+1)%DIM_BUF;&lt;br /&gt;
	&lt;br /&gt;
		if(sem_post(&amp;amp;empty) != 0)	// segnala un nuovo carattere non letto sul buffer&lt;br /&gt;
		{&lt;br /&gt;
			printf(&amp;quot;Error %i in producer: %s&amp;quot;,errno,strerror(errno));&lt;br /&gt;
			break;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void* consumer_routine(void * arg)&lt;br /&gt;
{&lt;br /&gt;
	FILE *file;&lt;br /&gt;
	&lt;br /&gt;
	if( (file = fopen(&amp;quot;./consumed.txt&amp;quot;,&amp;quot;a&amp;quot;)) == NULL)&lt;br /&gt;
	{&lt;br /&gt;
		printf(&amp;quot;Error %i in consumer: %s&amp;quot;,errno,strerror(errno));&lt;br /&gt;
		return NULL;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	while(1)&lt;br /&gt;
	{&lt;br /&gt;
		char c;&lt;br /&gt;
		&lt;br /&gt;
		if(sem_wait(&amp;amp;empty) != 0)	// se il buffer è vuoto si blocca&lt;br /&gt;
		{&lt;br /&gt;
			printf(&amp;quot;Error %i in consumer: %s&amp;quot;,errno,strerror(errno));&lt;br /&gt;
			break;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		fprintf(file,&amp;quot;%c&amp;quot;,buffer[next_read]);&lt;br /&gt;
		next_read = (next_read+1)%DIM_BUF;&lt;br /&gt;
		&lt;br /&gt;
		if(sem_post(&amp;amp;full) != 0)	// segnala che si è liberato un posto sul buffer&lt;br /&gt;
		{&lt;br /&gt;
			printf(&amp;quot;Error %i in consumer: %s&amp;quot;,errno,strerror(errno));&lt;br /&gt;
			break;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	close(file);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char* argv[])&lt;br /&gt;
{&lt;br /&gt;
	pthread_t producer, consumer;&lt;br /&gt;
	int *error, i;&lt;br /&gt;
	&lt;br /&gt;
	for(i=0; i&amp;lt; DIM_BUF; i++)&lt;br /&gt;
		buffer[i] = 0;&lt;br /&gt;
	&lt;br /&gt;
	if(sem_init(&amp;amp;empty,THREAD_SHARED,0) != 0)	// inizializzato a 0 perchè il buffer è vuoto&lt;br /&gt;
		return errno;&lt;br /&gt;
	if(sem_init(&amp;amp;full,THREAD_SHARED,DIM_BUF) != 0)	// servono DIM_BUF scritture per riempirlo&lt;br /&gt;
		return errno;&lt;br /&gt;
	&lt;br /&gt;
	pthread_create(&amp;amp;producer,NULL,&amp;amp;producer_routine,NULL);&lt;br /&gt;
	pthread_create(&amp;amp;consumer,NULL,&amp;amp;consumer_routine,NULL);&lt;br /&gt;
	&lt;br /&gt;
	pthread_join(producer, (void**)&amp;amp;error);	// aspetta la terminazione di producer&lt;br /&gt;
	printf(&amp;quot;End.\n&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
	return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>MV</name></author>
	</entry>
</feed>