2014-02-27 36 views
1

我正在学习如何在Boost库使用线程,我的搜索过程中,我发现下面的代码:void运算符()()了解

struct count 
{ 
    count(int id) : id(id) {} 

    void operator()() 
    { 
     for (int i = 0; i < 10; ++i) 
     { 
      boost::mutex::scoped_lock 
      lock(io_mutex); 
      std::cout << id << ": " << i << std::endl; 
     } 
    } 
    int id; 
}; 

int main(int argc, char* argv[]) 
{ 
    boost::thread thrd1(count(1)); 
    boost::thread thrd2(count(2)); 

    thrd1.join(); 
    thrd2.join(); 
    return 0; 
} 

这个程序工作正常,但我的问题是,什么是void operator()()函数的行为?因为有两个线程,每个线程都使用不同的值初始化计数。这是两个主要的count变量是单独创建的,所以他们的void operator()()应该是不同的每个变量。但似乎void operator()()是两个线程相同。在这个代码void operator()()还有一件事是不是从任何地方被调用,所以它如何运行?

有人能解释一下这个函数里面发生了什么吗?

void operator()() 
+0

是什么让你觉得它们对于两个线程都是一样的? –

+0

@JosephMansfield我运行这个程序检查互斥锁的工作情况,它显示了互斥锁的确切工作情况。它不允许其他线程在第一个线程完成之前处理此函数。 – nabeel

回答

4

这是一个棘手的语法。

boost::thread thrd1(count(1)); 
boost::thread thrd2(count(2)); 

在这些两行,operator()NOT直接调用。这里可见的count(n)构造函数。然后,将用'1'和'2'值构造的对象传递给thread对象,然后内部调用operator()在为此目的创建的不同线程上运行特定任务。

但是由于两个对象在它们的记忆中记住了不同的值(1/2),因此operator()中的通用代码在不同的实际值id字段上操作。这就是为什么操作员没有参数:所有必需的参数在构造过程中都存储在“count”对象中。

Btw。构造一个对象,并调用operator(),线是这样的:

count(1)(); 
+0

@JosephMansfield:谢谢,我已经自动粘贴了op-definition,而没有想到。 – quetzalcoatl

+0

但为什么它在内部调用运算符函数?意思是如果我定义了一些其他功能,它将不会以相同的方式运行。 – nabeel

+1

当你开始一个新的线程时(例如'boost :: thread'类),“线程”必须知道你想要的任务/任务/代码在该线程上运行。你**有**告诉它你想做什么_somehow_。而“告诉的方式”必须足够普遍,以便你能够给它任何你想要的工作。因此,'boost :: thread' _requires_你需要把这个工作放到一个operator()中。如果你遵守它,那么'boost :: thread'就可以简单地接受任何你给予的对象(例如“count”对象),创建线程,运行着名的operator()来形成你的对象,并且确保这个工作将被完成 – quetzalcoatl

0

操作者在C++超载的语法是:

返回型操作者操作者名称(参数); 示例:int运算符+(int其他) 此处的运算符名称为“+”。在你的情况下,它是“()”

现在在这里,你有2个线程实例,每个实例都有自己的count实例。当线程调用operator()()时,它会读取特定线程实例的计数值,这就是为什么您对同一个运算符有不同结果的原因。

0

它肯定会帮助您阅读代码的上下文在这里为其他读者发布一个链接:))。

没有任何其他上下文来帮助我,我猜这是一个演示boost :: thread的新学习者。我会假设你知道线程是如何工作的 - 如果你是新手,this link是一个很好的初学者概念参考。

进行分解:

boost::thread thrd1(count(1)); 
    boost::thread thrd2(count(2)); 

创建两个线程用不同的ID。正如@quetzalcoatl所提到的,boost线程接受一个函数对象,该对象定义了operator()()并在不同的线程中执行该运算符的内容。这意味着我们现在有3个线程 - 主执行线程和上面创建的2个线程。

thrd1.join(); 
    thrd2.join(); 

其他两个线程主执行线程等待加入 - 即完成他们的处理,并指示主线程,他们就完成了。当他们加入时,线程被终止(请注意,thrd1是一个boost线程对象 - 用于引用我们在幕后创建的实际线程,并且一直可用,直到栈结束)。

operator()()是一种监视方法。哪个线程正在运行和b。有多少'skipping-between-threads'发生。在解释之前,让我们看看结果。它很可能是这样的(但可能不完全):

1: 0 
1: 1 
2: 0 
2: 1 
2: 2 
2: 3 
1: 2 ...  

所以程序(在这种情况下)运行的线程#1两个循环,切换到线#2,运行了几个圈,又回到了#1并继续运行。 There is a reason两个线程都不能同时进入循环 - boost scoped_lock抓住(外部)io_mutex,将其锁定以供该线程使用,并继续运行,直到scoped_lock对象被销毁并释放io_mutex对象。这意味着,虽然两个线程并行运行,但在“scoped_lock”调用后,只有一个对象可以访问该特定堆栈。

希望有所帮助。