2

I'm stuck for about 2 days in the same situation and i'd really appreciate any help. The main thread is calling the initDevice() function, which is opening the file and creating a new thread, which he will be the "writing" thread, with the writeToDeviceHandler() function. The write2device() is called from main() and should insert new tasks to write (in the future) to a map<int,Task*>. The problem is, that sometimes the application is stuck at some kind of an inifinite loop or a deadlock and sometimes it writes <(# of tasks) to write. Can anyone see if there's anything wrong in the code? THANKS!

int write2device(char *buffer, int length)
{
    if(is_running)
    {
        pthread_mutex_lock(&tasks_mutex);//LOCK
        int curr_id = getNextAvailableId();
        Task* new_task = new Task(buffer,length, curr_id);
        tasks[curr_id] = new_task;
        pthread_cond_signal(&tasks_cv);
        given_ids.insert(curr_id);
        pthread_mutex_unlock(&tasks_mutex);//UNLOCK
        return curr_id;
    }
    return FAIL;
}

int initdevice(char *filename)
{
    is_running = true;
    pthread_cond_signal(&tasks_cv);
    output_file.open(filename);
    if(!output_file.is_open())
    {
        cerr << "Error opening file" << endl;
        is_running = false;
        return SYSTEM_ERROR;
    }
    int res = pthread_create(&writing_thread, NULL, writeToDeviceHandler, NULL);//Create the writing to file thread.
    if(res != 0)
    {
        cerr <<  "Error creating the writing thread" <<endl;
        exit(FAIL);
    }

    return SUCCESS;
}

void *writeToDeviceHandler(void *arg)
{
    Task* curr_task;
    while(is_running)
    {
        pthread_mutex_lock(&tasks_mutex);
        cout << "IN LOOP - size of db: " << tasks.size() << endl;
        if(tasks.empty())
        {
            pthread_cond_wait(&tasks_cv, &tasks_mutex);
        }
        if(tasks.empty()) cout << "Empty, still finding thread" <<endl;
        curr_task = tasks.begin()->second;
        if(curr_task == NULL)
        {
            pthread_mutex_unlock(&tasks_mutex);
            continue;
        }
        //copy from tasks to file
        output_file.write(curr_task->getBuff(), curr_task->getLength());

        ids.remove(curr_task->getId());
        tasks.erase(curr_task->getId());
        delete curr_task;
        pthread_mutex_unlock(&tasks_mutex);
    }

    pthread_exit(NULL);
    return NULL;
}
4

2 に答える 2

1

pthread_cond_wait呼び出しの周りにループがないという点で、コードは正しくありません。呼び出しは、pthread_cond_waitスプリアス ウェイクアップで戻る可能性があります。復帰後、起床状態確認する必要があります。あなたの場合、次のようになるはずです:

while (task.empty ())
  pthread_cond_wait(&tasks_cv, &tasks_mutex);

コードにはエラー チェックもありません。エラーがないか、すべての関数のすべての戻り値を確認してください。

于 2012-05-09T08:07:03.543 に答える