简体   繁体   中英

Need help templatizing structure accessed by multiple threads

The problem requires implementing a ring buffer into which a producer writes and from which a consumer reads. I have done this for a data type. I want to extend this so that it will work for any primitive data type but have not been able to figure out a good way to do this. I want the program to take inputs from the command line like so "program_name data_type size_of_buffer".
I could templatize the buffer.start pointer and pass the data type around but I don't know of a way to assign the data type name to a variable. Anyone have any ideas?

struct buffer{
    int * start;
    int size;
}buffer;

int * producer=NULL;
int * consumer=NULL;
bool donewriting;
bool sleeping;

void *mywrite(void *);
void *myread(void *);

void *mywrite(void * ){
    do{
        cout<<"In Thread 1"<<endl;
        static int x=0;
        *producer=x;
        cout<<"Write thread: wrote value "<<x<<" into buffer"<<endl;

        producer++;
        if(producer==buffer.start+10)
        {   producer=buffer.start;
            donewriting=true;
        }

        if(x==5)
        {
            cout<<"Thread 1 going to sleep"<<endl;
            Sleep(2000);
        }
        x++;
    } while(producer!=buffer.start);
}

void *myread(void *){
    while(!donewriting)
    {   //cout<<"In Thread 2"<<endl;
        if(consumer<producer)
        {  cout<<"Read thread: read value "<<*consumer<<" from buffer"<<endl;
            consumer++;
        }
    }
}

int main()
{
    buffer.size=10;
    buffer.start=new int(10);
    producer=buffer.start;
    consumer=buffer.start;
    donewriting=false;

    cout<<"In main"<<endl;
    pthread_t writeThread,readThread;
    pthread_create(&writeThread,NULL,mywrite,NULL);
    pthread_create(&readThread,NULL,myread,NULL);

    pthread_join(writeThread,NULL);
    pthread_join(readThread,NULL);
    return 0;
}

Unfortunately, your goal is not possible given the scenario you have described. Internally, C++ programs compile templated code for each datatype used with the template . In other words, if you have a templated function x() and you call

x<int>();
x<float>();

the compiler will produce two copies of the templated function: one that uses the int datatype and another that uses the float datatype. Before you call the function, no code is produced at all. Therefore, you cannot build the program and pass arbitrary data types to it.

Of course, if the command-line call is only intended as a test for the code, and you'll use it in a library in future, you're ok - but you'll still have to specify the type you're using in your code.

The current way you're doing this, using void * is probably the best way.

It might be better to specify the size in bytes of the type you wish to use, rather than the specific type itself. As long as your final producer and consumer share knowledge of the type in question, you'll be fine.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM