c ++ pthreads对全局char缓冲区的操作

时间:2014-04-03 02:48:45

标签: c++ pthreads

我正在尝试使用pthreads。我正在尝试创建三个线程并让它们在全局char缓冲区上运行。我正在使用互斥锁和解锁他们的关键部分。程序流程应该是:Main产生三个线程。线程一锁,初始化缓冲区,打印出来,发出第二个线程信号并解锁。线程2进入其关键部分操作缓冲区并发出信号线程三等等。它似乎有效。其他时候,看起来好像是在旋转锁中吮吸。任何正确方向的帮助都会很棒。感谢。

#include <pthread.h>  
#include <string.h>  
#include <unistd.h>  
#include <iostream>

using namespace std;

const int num_threads = 3;

char buffer[100]; 
pthread_mutex_t buffer_mutex = pthread_mutex_initializer; 
pthread_cond_t buffer_cond = pthread_cond_initializer;



void* firstthreadfunc(void* proc) { 
    string a = "data received";
    pthread_mutex_lock(&buffer_mutex);

    sleep(1);
    cout<<"threadone"<<endl;    
    for(int i = 0;i<14;i++){
        buffer[i] = a[i];
        cout<<buffer[i];
    }
    cout<<endl;

    pthread_cond_signal(&buffer_cond);   

    pthread_mutex_unlock(&buffer_mutex);
    return null; 
} 

void* secondthreadfunc(void* proc) { 
    string a = "data processed"; 

    pthread_mutex_lock(&buffer_mutex);
    pthread_cond_wait(&buffer_cond, &buffer_mutex);

    sleep(1);
    cout<<"threadtwo"<<endl;        
    for(int i = 0; i<15 ;i++){
        buffer[i] = a[i];
        cout<<buffer[i];
    }   
    cout<<endl;  

    pthread_cond_signal(&buffer_cond);
    pthread_mutex_unlock(&buffer_mutex);
    return null; 
}

void* thirdthreadfunc(void* proc) { 

    string a = "data sent";
    pthread_mutex_lock(&buffer_mutex);
    pthread_cond_wait(&buffer_cond, &buffer_mutex); 
    sleep(1);

    cout<<"thread three"<<endl;
    for(int i = 0;i<9;i++){
        buffer[i] = a[i];
        cout<<buffer[i];
    }
    cout<<endl;

    pthread_cond_signal(&buffer_cond);
    pthread_mutex_unlock(&buffer_mutex);
    return null; 
}


int main() {

    pthread_t  p_threadone, p_threadtwo, p_threadthree;;

    pthread_attr_t attr;
    pthread_attr_init(&attr);

    for(int i = 0;i<100;i++){
        buffer[i] = 'a';
    }


    //create threads
    cout<<"creating threads"<<endl; 
    pthread_create(&p_threadone, &attr, firstthreadfunc, null);
    pthread_create(&p_threadtwo, &attr, secondthreadfunc, null);
    pthread_create(&p_threadthree, &attr, thirdthreadfunc, null);


    //terminate threads
    pthread_join(p_threadone,null);
    pthread_join(p_threadtwo,null);
    pthread_join(p_threadthree,null);



    return 0;




}

感谢WhozCraig和Tony,您的答案解决了这个问题。我明白我做错了什么。

1 个答案:

答案 0 :(得分:2)

首先,你被困在哪里。 thread2或thread3中的以下行是关键点:

pthread_cond_wait(&buffer_cond, &buffer_mutex);

到现在为止你要问,&#34;为什么?&#34;因为你把条件变量误认为是一个状态;不是信令机制。条件变量旨在用于向感兴趣的服务员发送其他状态变化的信号:谓词。你没有。请考虑以下修改后的代码版本。

这使用两个谓词值(我建议你坚持每个condvar一个,直到你对它们变得更加舒服;开始简单),用相同的互斥锁保护它们并用相同的条件变量发出它们的变化。需要注意的重要一点是,我们不会等待条件变量,直到我们知道我们等待的谓词尚未准备就绪。由于我们锁定了互斥锁,我们可以安全地检查谓词:

#include <iostream>
#include <string>
#include <unistd.h>
#include <pthread.h>
using namespace std;

const int NUM_THREADS = 3;

char buffer[100];
bool bDataReady = false;
bool bDataWaiting = false;

pthread_mutex_t buffer_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t buffer_cond = PTHREAD_COND_INITIALIZER;


void* firstThreadFunc(void* proc)
{
    string a = "Data Received";

    pthread_mutex_lock(&buffer_mutex);
    cout<<"ThreadOne"<<endl;
    std::copy(a.begin(), a.end(), buffer);
    buffer[a.size()] = 0;
    cout << buffer << endl;

    bDataReady = true;
    pthread_cond_broadcast(&buffer_cond);
    pthread_mutex_unlock(&buffer_mutex);
    return NULL;
}

void* secondThreadFunc(void* proc)
{
    string a = "Data Processed";

    pthread_mutex_lock(&buffer_mutex);
    while (!bDataReady)
        pthread_cond_wait(&buffer_cond, &buffer_mutex);

    cout<<"ThreadTwo"<<endl;
    std::copy(a.begin(), a.end(), buffer);
    buffer[a.size()] = 0;
    cout << buffer << endl;

    bDataReady = false;
    bDataWaiting = true;
    pthread_cond_broadcast(&buffer_cond);
    pthread_mutex_unlock(&buffer_mutex);
    return NULL;
}

void* thirdThreadFunc(void* proc) 
{
    string a = "Data Sent";
    pthread_mutex_lock(&buffer_mutex);

    while (!bDataWaiting)
        pthread_cond_wait(&buffer_cond, &buffer_mutex);

    cout<<"Thread Three"<<endl;
    std::copy(a.begin(), a.end(), buffer);
    buffer[a.size()] = 0;
    cout << buffer << endl;

    bDataWaiting = false;
    pthread_cond_broadcast(&buffer_cond);
    pthread_mutex_unlock(&buffer_mutex);
    return NULL;
}


int main() {

    pthread_t  p_threadOne, p_threadTwo, p_threadThree;;

    pthread_attr_t attr;
    pthread_attr_init(&attr);

    for(int i = 0;i<100;i++){
        buffer[i] = 'a';
    }


    //create Threads
    cout<<"creating threads"<<endl;
    pthread_create(&p_threadOne, &attr, firstThreadFunc, NULL);
    pthread_create(&p_threadTwo, &attr, secondThreadFunc, NULL);
    pthread_create(&p_threadThree, &attr, thirdThreadFunc, NULL);


    //terminate Threads
    pthread_join(p_threadOne,NULL);
    pthread_join(p_threadTwo,NULL);
    pthread_join(p_threadThree,NULL);

    return 0;
}

<强>输出

creating threads
ThreadOne
Data Received
ThreadTwo
Data Processed
Thread Three
Data Sent