多线程给出了一些奇怪的结果

Multi Threading gives some weird results

本文关键字:结果 多线程      更新时间:2023-10-16

我只是使用了多线程。它可以工作,但它给出了一些奇怪的结果,每次我运行程序时,结果都不同。谁能告诉我我做错了什么

现在在我的输出中,

我应该有 2 个块,它们不断上下移动,但在实际输出中,其他一些块突然出现,您可以在链接中看到我的输出

(即我从主代码中排除了全局字符数组,我正在添加另一个代码部分,以便您可以运行我的代码并帮助我(

主代码

#include<iostream>      //libraries
#include<stdio.h>
#include<conio.h>
#include<windows.h>
#include<thread>
using namespace std;
void print();
void gotoxy(int,int);
int race();
void block1();
void block2();
COORD coord={0,0};//global variable
    char road[22][80]={//haven't mentioned the array  }; //global char array 
void main()
{
    race(); 
}
int race()
{
        char swap;
    //printing the array once
    cout<<endl;
    for(int i=0 ; i<22 ; i++)
    {
        for(int j=0 ; j<80 ; j++)
        {
            cout<<road[i][j];
        }
    }
    thread t1 (block2);
    thread t2 (block1);
    t1.join();
    t2.join();
  getch();
  return 0;
}
void block1()           //definition of block1
{
    char swap;
    int i=1 , j=4;
    while(!kbhit())
    {
        while(road[i+1][j]!='xdb')
        {
            swap=road[i][j];
            road[i][j]=road[i+1][j];
            road[i+1][j]=swap;
            gotoxy(4,i+1);
            cout<<road[i][j];
            gotoxy(4,i+2);
            cout<<road[i+1][j];
            Sleep(200);
            i++;
        }
        if(road[i+1][j]=='xdb')
        while(road[i-1][j]!='xdb')
            {
            swap=road[i][j];
            road[i][j]=road[i-1][j];
            road[i-1][j]=swap;
            gotoxy(4,i);
            cout<<road[i-1][j];
            gotoxy(4,i+1);
            cout<<road[i][j];
            Sleep(500);
            i--;
            }
     }
}
void block2()           //definition of function block2
{
    char swap;
    int i=1 , j=7;
    while(!kbhit())
    {
        while(road[i+1][j]!='xdb')
        {
            swap=road[i][j];
            road[i][j]=road[i+1][j];
            road[i+1][j]=swap;
            gotoxy(7,i+1);
            cout<<road[i][j];
            gotoxy(7,i+2);
            cout<<road[i+1][j];
            Sleep(50);
            i++;
        }
        if(road[i+1][j]=='xdb')
        while(road[i-1][j]!='xdb')
            {
            swap=road[i][j];
            road[i][j]=road[i-1][j];
            road[i-1][j]=swap;
            gotoxy(7,i);
            cout<<road[i-1][j];
            gotoxy(7,i+1);
            cout<<road[i][j];
            Sleep(50);
            i--;
            }
    }
}

全局字符数组

char road[22][80]={        //global char array 
'xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb',
'xdb','.','.','.','xdb','.','.','xdb','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','xdb',
'xdb','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','xdb',
'xdb','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','xdb',
'xdb','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','xdb',
'xdb','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','xdb',
'xdb','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','xdb',
'xdb','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','xdb',
'xdb','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','xdb',
'xdb',1,'.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','xdb',
'xdb','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','xdb',
'xdb','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','xdb',
'xdb','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','xdb',
'xdb','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','xdb',
'xdb','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','xdb',
'xdb','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','xdb',
'xdb','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','xdb',
'xdb','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','xdb',
'xdb','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','xdb',
'xdb','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','xdb',
'xdb','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','xdb',
'xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb','xdb',

                        };

当您输出到屏幕时,您有竞争条件。例如,如果线程 1 正在运行

        gotoxy(4,i+1);
        cout<<road[i][j];

并在gotoxy(4,i+1);后执行切换到线程 2。然后线程 2 执行自己的

操作
        gotoxy(7,i+1);
        cout<<road[i][j];

输出光标的位置现在为 (8, i+1(。然后,当线程 1 再次运行时,它将使用 cout<<road[i][j]; 输出到当前光标,该游标位于不正确的位置。

要解决这个问题,你必须使用种族保护机制,正如πάντα ῥεῖ所说。像互斥锁这样的东西会起作用。

您有争用条件,因为road是在多个线程中读取和写入的。您需要保护两个线程中对数组的每次访问。只有"打印数组一次"循环才没问题,因为它在生成其他线程之前运行。

// global scope
std::mutex road_mx;
// ...
void block1() {
    while //... {
        // ...
        while(road[i+1][j]!='xdb') {  // <-- problem, see below
            {  // <-- scope for the lock guard
                std::lock_guard<std::muxtex> lock(road_mx);
                // do stuff with road
            }
            // ...
        }
    }
}
// ...

在 while 条件下访问road是一个问题。您可能不想在整个 while 循环周围放置一个lock_guard,因为在锁下花费的时间越少,线程之间的争用就越少,程序运行的速度就越快。

最简单的解决方案是引入局部变量,将值从数组复制到其中。这些是当前线程的本地(即独占(,因此不需要保护。