pthreads 的严格交替,c++

Strict alternation for pthreads, c++

我是 c++ 的新手,现在正试图理解一段代码。它是关于Pthreads的严格交替。

line 1:  #include <iostream>
line 2:  #include <pthread.h>
line 3:  #include <stdlib.h>
line 4: 
line 5:  int count;
line 6:  int turn = 0;
line 7:
line 8:  void* function(void* arg){
line 9:    int actual_arg = *((int*) arg);
line 10:   for(unsigned int i = 0; i < 10; ++i) {
line 11:     while(turn != actual_arg);
line 12:       count++
line 13:    std::cout << "Thread #" << actual_arg << " count = " << count << std::endl; 
line 14:    if(actual_arg==0){
line 15:      turn =1;
line 16:      }else {
line 17:        turn =0;
line 18:        }
line 19:   int max = rand() % 100000;
line 20:   for(int x = 0; x < max; x++);
line 21:  }
line 22:   pthread_exit(NULL);
line 23: }

我的问题是: 为什么第一个for循环使用unsigned int(第10行),是因为第9行声明了指针值arg吗? 什么是第 11 行?我有点知道这是关于检查 actual_arg 中的线程,但是,我仍然对该行感到困惑。 对于第 14 到 18 行,由于 turn 值只会是 1 或 0,所以我们在这里使用 if 语句来检查值? 最后一个是第 19 行和第 20 行,我们真的需要这些代码吗?那是为了什么?

感谢您回答这些问题,如果您能帮助我详细解释这段代码,将不胜感激。

我不知道这是你的代码还是其他人的,但它有问题。

line 5:  int count;
line 6:  int turn = 0;
line 7:
line 8:  void* function(void* arg){
line 9:    int actual_arg = *((int*) arg);
line 10:   for(unsigned int i = 0; i < 10; ++i) {
line 11:     while(turn != actual_arg);
line 12:       count++
line 13:    std::cout << "Thread #" << actual_arg << " count = " << count << std::endl; 
line 14:    if(actual_arg==0){
line 15:      turn =1;
line 16:      }else {
line 17:        turn =0;
line 18:        }
line 19:   int max = rand() % 100000;
line 20:   for(int x = 0; x < max; x++);
line 21:  }
line 22:   pthread_exit(NULL);
line 23: }

你问过这个:

line 10:   for(unsigned int i = 0; i < 10; ++i) {

这可能是 intunsigned int,因为它永远不会是负数。它与其他任何事情都完全无关。变量本身就是为了确保你循环 10 次。

其余的做什么?

假设我们启动了两个线程,0 和 1。

line 11:     while(turn != actual_arg);
line 12:       count++;

(顺便说一句,你错过了;)。

这叫做busy-sleep。这不好。它在等待轮到你的时候咀嚼大量 CPU。有更好的方法。然而,线程 0 将跳过这个。线程 1 将等待。

line 13:    std::cout << "Thread #" << actual_arg << " count = " << count << std::endl; 

线程 1 仍在等待,但线程 0 将打印出一个未知的计数 -- 因为线程 1 正在疯狂地旋转,这是发生的旋转量的计数。 count 会变得非常快,并且可能会在 10 个循环完成之前翻滚。

line 14:    if(actual_arg==0){
line 15:      turn =1;
line 16:      }else {
line 17:        turn =0;
line 18:        }

这只是在 0 和 1 之间来回翻转。线程 0 会将转向设置为 1,以便线程 1 可以 运行。

line 19:   int max = rand() % 100000;
line 20:   for(int x = 0; x < max; x++);

这是另一个可怕的 busy-sleep。这是咀嚼时间的尝试,但它也咀嚼了大量 CPU。再次。不要这样做。使用睡眠方法。

我不知道你从哪里得到这段代码,但这是一个关于如何进行多线程处理的糟糕例子。不要将此用作您的学习示例。

Why the first for loop use unsigned int(line 10), is that because of the declaration of the pointer value arg in line 9?

没有特别的原因。 intshortunsigned long long 或任何其他整数类型都可以正常工作。就特别选择 unsigned int 而言,我无法谈论该代码作者的决策过程。我自己会使用 int,但是使用 unsigned int.

并没有什么特别的错误

What is line 11? I kind of know it is about checking thread in actual_arg, however, I am still confused for that line.

它循环直到条件 turn != actual_arg 的计算结果为 0(假)。这似乎是为了使线程 busy-wait 直到轮到它为止,但是

  1. 太可怕了,而且
  2. 它包含数据竞争,因此很可能根本无法工作。

这里更合适的做法是使用条件变量来帮助线程暂停操作,直到轮到它为止。这也将涉及一个互斥锁,除其他外,它可以用来保护共享数据,从而避免数据竞争。

For lines 14 to 18, since the turn value will only be 1 or 0 so we use an if statement to check the value here?

基本上是的。该代码似乎旨在设置 turn 以指示现在轮到另一个线程,但这涉及另一个数据竞争。必须保护 turn 变量不被多个线程通过互斥锁或类似的同步对象并发访问。

The last one is for lines 19 and 20, are we really need those codes? what is that for then?

其意图似乎是让线程在循环返回以尝试进行另一轮之前花费随机时间。也许这是为了模拟 真正的 计算工作量。但是,这不一定有效,因为编译器可以轻松优化整个 for 循环。如果有效,那就太浪费了。


总的来说,我同意你的另一个答案:提供的代码很糟糕。把它扔掉。不要把它当作任何事情的好例子。