开发者

Pthread condition variable unpredictable outcome

开发者 https://www.devze.com 2023-03-20 22:42 出处:网络
First of all sorry for posting a long question, but please do keep patience :). As a part of my application i am using threads to read different parts of a memory mapped file, as in first half of t

First of all sorry for posting a long question, but please do keep patience :).

As a part of my application i am using threads to read different parts of a memory mapped file, as in first half of the mapped file is read and processed by main thread and the second half of the mapped file is read and processed by another thread.

I am using a condition variable, to make sure that the second thread waits until the main thread populates the file related values in a structure.

Using this methodology I get the file size populated correctly sometimes and sometimes its not showing correctly.

Here is the applicable code :

void * thread_proc(void * arg){

    struct thread_related_data * dat_str = (struct thread_related_data *) arg;

    //pthread_detach(pthread_self());

    pthread_mutex_lock(&(dat_str->mutex));

    while(dat_str->thread_indicator == 0 ){
        pthread_cond_wait(&(dat_str->cond),&(dat_str->mutex));
    }

    if(dat_str->thread_indicator == 1){   // Start data processing

// start processing bottom half of the mapped file and insert data into &dat_str->thread_proc_data

        pthread_mutex_unlock(&(dat_str->mutex));
        printf ("Got conditioned\n");

        int bytes = dat_str->file_size - dat_str->start_bytes; // bytes should have almost half of the length of the file in bytes, but it does not always pri开发者_StackOverflow社区nt the value correctly in the next statement .

        printf(" Bytes :: %d\n", dat_str->start_bytes); // Sometimes this line gets printed twice ..dont know how !!!

        char *start;
        int i = 0;
        while(i <= bytes){
            start = dat_str->file;
            while(*(dat_str->file) != '\n'){
                //printf file++;
            }

            line_proc(start,static_cast(dat_str->file - start - 1),dat_str->phrase);
            dat_str->file++;
            i++;
        }

    }
    return NULL;
}


void inputFile::start_processing(common& com , searchable& phrases){
    pthread_create(&thread1,NULL,thread_proc,&trd);
    //trd.fil_obj = this;
    // Set the char pointer for the thread

    char * temp = file; // pointer to memory mapped file
    temp += file_size/2;
    //cout.setf(std::ios::unitbuf);
    int bytes = temp - file;

    while(*temp != '\n'){
        bytes++;
        temp++;
    }

    if(*temp == '\n'){
        temp++;

        pthread_mutex_lock(&(trd.mutex));
        trd.thread_indicator = 1;         // signalling variable
        trd.file = temp;
        trd.phrase = phrases.text_to_search[0];
        trd.start_bytes = bytes + 1;     // the start pointer of the mapped file
                                                 // for the second thread.
                                                 // i.e second thread will start processing                         from this pointer
        pthread_cond_signal(&(trd.cond));
        pthread_mutex_unlock(&(trd.mutex));

        // Now process half of the file and put the results in record vector

        temp--; // this thread will process upto '\n' first half of the file
         }
}

Please let me know where have I made a logical flaw or have I implemented the condition variables in a wrong way.

Also, I have initialized both mutex and the condition variable as pthread_mutex_init(&(trd.mutex),NULL) and pthread_cond_init(&(trd.cond),NULL) instead of PTHREAD_MUTEX_INITIALIZER and PTHREAD_COND_INITIALIZER respectively. Would that be a reason of my problem?

Thanks.


Your use of the condition variable for sleeping is slightly off, the usual method is:

while(!condition)
{
    pthread_cond_wait(...);
}

This handles the case of spurious wakeups (which may happen). Your current code is not checking any condition, but should probably be changed to something like the following:

while (dat_str->thread_indicator != 1)
{
    pthread_cond_wait(&(dat_str->cond),&(dat_str->mutex));
}


Probably not the real problem. But you should be careful you do not always unlock the mutex

    pthread_mutex_lock(&(dat_str->mutex));

    while(dat_str->thread_indicator == 0 )
    {    pthread_cond_wait(&(dat_str->cond),&(dat_str->mutex));
    }

    if(dat_str->thread_indicator == 1)
    {
        // CODE    

        pthread_mutex_unlock(&(dat_str->mutex));

        // MORE CODE
    }
    // What happens if it is not 1? The lock is still held.

    return NULL

What happens if the file does not contain '\n'

while(*temp != '\n') // You may want to test against the last good location.
{
    bytes++;
    temp++;
}
0

精彩评论

暂无评论...
验证码 换一张
取 消