2012-10-06 68 views
1

我是线程(和C/C++)的新手,我尝试使用多线程来访问共享变量。在共享变量的C++中使用pthread的多线程

在main中,我创建了一个变量char inputarray [100];

线程1:该线程将以2字节的突发读取stdin中的数据,并将它们附加到输入数组。 (通过输入文件输入)

线程2:此线程将一次读取1个字节的数据,执行计算并将其数据放入输出数组中。

线程3:该线程将以2个字节的突发从输出数组输出数据。 (标准输出)

我试过输入部分,并通过传递一个结构得到它的工作,但是想要做到这一点而不使用结构,但它一直给我的问题。

如果我可以得到输入,我相信我可以使用类似的策略来完成输出。任何帮助将不胜感激。

下面是输入线程的粗略模板。

#include <stdio.h> 
#include <pthread.h> 

using namespace std; 

void* input(void* arg) { 
    char reading[3]; 
    fread(reading,1,2,stdin); 

    //append to char inputarray[]..??? 
} 

int main() { 
    char inputarray[100]; 
    pthread_t t1; 
    pthread_create(&t1, NULL, &input, &inputarray); 
    void *result; 
    pthread_join(t1,&result); 
    return 0; 
} 

回答

2

你是正确的轨道上:

作为一个说明并行线程库是C库,所以你需要声明回调的C函数:

extern "C" void* input(void* arg); 

个人而言,我会通过第一个元素的地址:

pthread_create(&t1, NULL, &input, &inputarray[0]); 

然后这会让你的代码看起来像这样:

void* input(void* arg) { 

    try 
    { 
     char* inputarray = (char*)arg; 
     size_t inputLocation = 0; 

     // Need to make sure you don't over run the buffer etc... 
     while(!finished()) 
     { 
      fread(&inputarray[inputLocation],1,2,stdin); 
      inputLocation += 2; 
     } 
    } 
    catch(...){} // Must not let exceptions escape a thread. 
    return NULL; 
} 

这种风格的麻烦在于您将协调责任置于每个单独的线程中。编写器线程必须检查读取器线程是否必须检查数据是否可用等等。所有这些都需要协调,所以现在您需要一些共享的互斥锁和条件变量。

更好的选择是将这个责任转移到沟通的对象中。所以我会创建一个具有通信所需的基本操作的类,然后使其方法执行适当的检查。

class Buffer 
{ 
    public: 
     void write(......); // 
     void read(.....); // 
    private: 
     // All the synchronization and make sure the two threads 
     // behave nicely inside the object. 
}; 

int main() 
{ 
     pthread_t threads[3]; 
     std::pair<Buffer, Buffer> comms; 
     // comms.first  inputToRead 
     // comms.second processesToOutput 


     pthread_create(&threads[0], NULL, &readInput, &comms.first); // Input 
     pthread_create(&threads[1], NULL, &procInput, &comms);   // Processing 
     pthread_create(&threads[2], NULL, &genOutput, &comms.second); // Output 

     void *result; 
     pthread_join(threads[0],&result); 
     pthread_join(threads[1],&result); 
     pthread_join(threads[2],&result); 

} 

补充说明:

除非有一些非常奇怪的有关数据处理。这可能会更快地写成单线程应用程序。

+0

谢谢你的回应,这是非常有帮助的。为了解决您的问题,这是一种处理数据的非常奇怪的方式。我正在试图为线程难以置信的特定数据文件起草一个模板。作为一个短期目标,我试图优化一个小型程序,该程序需要2 kb数据块中的2.5 MB数据。至于单线程应用程序,我目前有这样的程序,并且出于纯粹的好奇心,我想尝试线程以查看速度是否完全不同。 –

8

几个问题:

  1. 我认为堆叠阵列的共享变量非常糟糕的选择,因为它有一个固定的大小,它不是从线程2清晰和3往哪里放新元素或从哪里读取元素。我建议改用std::vectorstd::deque。 最初你的容器是空的。然后线程2将一些元素推送给它。 线3轮询(或等待条件变量)的容器,一旦发现新的元素 - 它们打印

  2. 必须同步与互斥访问共享变量(考虑并行线程互斥,std::mutexboost::mutex)。您可能还想使用条件变量来通知线程3有关队列中的新元素。但是对于初始实施而言,这不是必需的。

  3. 你真的必须使用pthread原语吗?通常情况下,使用std::thread,std::mutex(如果您有现代编译器)或,boost::mutex则更容易和更安全(即异常安全)。