Visualizzazione dei risultati da 1 a 5 su 5

Discussione: [C++] Bounded Buffer

  1. #1

    [C++] Bounded Buffer

    Salve,

    sto costruendo un sistema di buffer per passare dei data dal "Producer" al "Consumer" all'interno di un programma. Dato che il rapporto tra "Producer" e "Consumer" è uno -> molti ho bisogno di fare una collezione di buffers così che il "Producer" scriverà su tutti gli elementi della collezione:

    Tuttavia non so se per implementare questo sistema sia meglio usare std::vector oppure std::list

    Inoltre il "Consumer" una volta che non avrà pià bisogno del buffer dovrà uscire dalla collezione stessa per evitare che il "Producer" perda tempo a scrivere dei dati in un area non più utilizzata!

    Per portare questa idea in codice ho deciso che scriverò un programma che fa utilizzo di socket dove un thread principale "Producer" scriverà su una colelzione buffers il timestamp del momento. Ad ogni connessione (userò telnet) verrà lanciato un nuovo thread che si /registra/ nella collezione di buffers e ne legge il contenuto all'infinito, una volta chiusa da me la connesione telnet il thread si cancellerà dalla collezione e ritornerà al main().

    la collezione di buffers avrà scope globale per essere accesibile sia da Producer che Consumer.

    Un esempio in sintesi, del corpo del programma senza aver ancora implementato il sistema di buffers è il seguente:

    codice:
    #define _CRT_SECURE_NO_WARNINGS
    #include <iostream>
    #include <string>
    #include <process.h>
    #include <cstdlib>
    #include <ctime>
    #include "socket.h"
    using namespace std;
    
    const string CRLF = "\r\n";
    
    unsigned int __stdcall handleClient(void* sock);
    string getDateTime(void);
    
    int main()
    {
    	// Set up server (port: 8000, maxconn: 10)
    	SocketServer sockIn(8000, 10);
    
    	while(1)
    	{
    		// ...wait for incoming connections...
    		Socket* s = sockIn.Accept();
    		unsigned int sockRet;
    		_beginthreadex(0,0,handleClient,s,0,&sockRet);
    		if(sockRet)
    			cout << "Spawned a new thread!" << endl;
    	}
    
    	sockIn.Close();
    
    	system("pause");
    	return EXIT_SUCCESS;
    }
    
    // handleClient
    unsigned int __stdcall handleClient(void* sock)
    {
    	Socket* s = (Socket*) sock;
    
    	// Send line
    	s->SendBytes("Thanks for connecting..." + CRLF);
    
    	while(1)
    	{
    		Sleep(3000);
    		int ret = s->SendBytes("Time is: " + getDateTime() + CRLF);
    
    		if(SOCKET_ERROR == ret)
    			break;
    	}
    
    	// Disconnect client
    	cout << "Closing thread..." << endl;
    	s->Close();
    	delete s;
    	return 0;
    }
    
    // getDateTime (Fri, 10 Oct 2008 14:41:59 GMT)
    string getDateTime(void)
    {
    	time_t rawtime;
    	struct tm * timeinfo;
    	time(&rawtime);
    	timeinfo = gmtime(&rawtime);
    	char buffer[30];
    	strftime(buffer,30,"%a, %d %b %Y %X GMT",timeinfo);
    	return static_cast<string>(buffer);
    }
    Come posso collegare tra di loro istanza e presenza nella lista? questo perchè alla fine l'istanza deve togiere la sua presenza nella lista!

    grazie
    Alla batteria dai retta ballA

  2. #2
    per adesso mi è venuto in mente solo questo, con la seguente definisco un buffer circolare:

    codice:
    struct Buffer // Semplice buffer
    {
    	unsigned char * data;        // data container (0-255)
    	unsigned short bufferlength; // data length    (0-65535)
    	bool flag;                   // free/used      (false/true)
    };
    
    struct Collector // Collezione di buffers
    {
    	std::list<Buffer*> buff(numbuffer)
    };
    Quindi il buffer sul quale il Producer scriverà è: "Collector" che è composta da numbuffer di "Buffer"...
    Alla batteria dai retta ballA

  3. #3
    e cmq a pensarci bene...il Producer non deve fare push_back, ma push_front (insert)

    sto facendo degli esperimenti con Boost:
    http://www.boost.org/doc/libs/1_41_0...ar_buffer.html

    codice:
    int main()
    {
    
    	circular_buffer<int> cb(3);
    	circular_buffer<int>::const_iterator it;
    
    	cb.push_back(2008);
    	cb.push_back(2009);
    	cb.push_back(2010);
    	cb.push_back(2011); // 2008 is removed
    
    	for(it=cb.begin(); it!=cb.end(); ++it)
    	{
    		cout << *it << " ";
    	}
    
    	system("pause");
    	return EXIT_SUCCESS;
    }
    Alla batteria dai retta ballA

  4. #4
    diciamo che non ha molta importanza alla fine se inserisco il dato con push_back oppure push_front...nel prima caso so che il dato più vecchio è all'inizio della catena quindi lo leggo e poi rimuovo con pop_front() viceversa nel secondo caso....

    codice:
    #define _CRT_SECURE_NO_WARNINGS
    #include <windows.h>
    #include <iostream>
    #include <vector>
    #include <string>
    #include <cstdlib>
    #include <ctime>
    #include <boost/circular_buffer.hpp>
    using namespace std;
    using namespace boost;
    
    string getDateTime(void);
    
    int main()
    {
    
    	circular_buffer<string> cb(3);
    	circular_buffer<string>::const_iterator it;
    
    	cb.push_front(getDateTime());
    	cout << getDateTime() << endl;
    	Sleep(1000);
    
    	cb.push_front(getDateTime());
    	cout << getDateTime() << endl;
    	Sleep(1000);
    
    	cb.push_front(getDateTime());
    	cout << getDateTime() << endl << endl;
    
    	string last = cb[2];
    
    	cout << endl << last << endl;
    
    	system("pause");
    	return EXIT_SUCCESS;
    }
    
    // getDateTime (Fri, 10 Oct 2008 14:41:59 GMT)
    string getDateTime(void)
    {
    	time_t rawtime;
    	struct tm * timeinfo;
    	time(&rawtime);
    	timeinfo = gmtime(&rawtime);
    	char buffer[30];
    	strftime(buffer,30,"%a, %d %b %Y %X GMT",timeinfo);
    	return static_cast<string>(buffer);
    }
    Alla batteria dai retta ballA

  5. #5
    forse questa è l'idea definitiva per implementare il meccanismo:

    codice:
    // declare
    typedef unsigned int regkey;
    typedef struct {...} buffer;
    
    // global buffer
    std::map<regkey, buffer> clients
    
    // a client connect (add consumer)
    clients.insert(makepair(regkey, buffer));
    
    // a client disconnect (remove comsumer)
    clients.remove(regkey);
    
    // Producer writes to every element in the map(clients)
    (...)
    dove regkey è un numero casuale creato con srand
    Alla batteria dai retta ballA

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.