多线程中的同步

Synchronization in multithreading

如何同步这 9 个线程,以便它们在主线程之前执行?

我想检查大小为 9 的二维数组中行的有效性。每行应包含值(1 到 9)。 为此,我在主线程中创建了一个名为 "void* checkingRows(void* arg)" 的线程,并将其与主线程连接起来。 然后线程 checkingRows 正在创建另外 9 个线程,这些线程正在检查每一行的有效性。

````````````````````````````````````
Pthread_t id1;
pthread_mutex_t mut1;
int arr[9][9] = {  
                    {6,2,4,5,3,9,1,8,7},
                    {6,6,9,7,2,8,6,3,4},
                    {8,3,7,6,1,4,2,9,5},
                    {1,4,3,8,6,5,7,2,9},
                    {9,5,8,2,4,7,3,6,1},
                    {7,6,2,3,9,1,4,5,8},
                    {3,7,1,9,5,6,8,4,2},
                    {4,9,6,1,8,2,5,7,3},
                    {2,8,5,4,7,3,9,1,6}
                };
````````````````````````````````````
void* rowCheck(void* arg){
    int* argument = (int*) arg;
    int idx = *argument;
    int count = 0;
    for(int i = 0; i < 9; i++){
        int temp = arr[idx][i];
        count = 0;
        for(int j = i; j < 9; j++){
            if(arr[idx][j] == temp || arr[idx][j] <= 0 || arr[idx][j] >= 10){
                count++; 
            }
            if(count > 1){
                pthread_mutex_lock(&mut1);
                count = 0;
                cout<<"ERROR at"<<arr[idx][j]<<endl;
                pthread_mutex_unlock(&mut1);
                break;
            }
        }
    }
    pthread_exit(NULL);
}

````````````````````````````````````
void* checkingRows(void* arg){
    int *row = new int;
    *row = 0;
    for(int i = 0; i<gridSize; i++){
        pthread_create(&workerIdRow[i], NULL, &rowCheck, row);
        *row = *row + 1;
    }
    pthread_exit(NULL);
}
`````````````````````````````````
int main(){

    pthread_mutex_init(&mut1, NULL);
    pthread_create(&id1, NULL, &checkingRows, NULL);
    pthread_join(id1,NULL);

    retrun 0;

}
````````````````````````````````````

ERROR at 6
ERROR at 6

第一个创建的线程是无用的,因为你创建它并立即等待它结束

相反你不等待其他9个线程结束,所以你在他们结束之前退出

当您启动子线程时,您没有同步来确保它们有时间在为下一个线程修改它之前读取行号,多个可以检查同一行。为此,您可以使用一个条件(仍然使用 C 线程库),或者您可以每次给新创建的 int 给定索引。

你有内存泄漏,因为你没有删除int,实际上在你的情况下在堆中分配它是没有用的


你的代码中的一个建议,如你所见,我直接将相关行的地址给每个线程,我删除了中间线程并等待9个线程结束,更多其他更改

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

pthread_mutex_t mut1;

int arr[9][9] = {  
                    {6,2,4,5,3,9,1,8,7},
                    {6,6,9,7,2,8,6,3,4},
                    {8,3,7,6,1,4,2,9,5},
                    {1,4,3,8,6,5,7,2,9},
                    {9,5,8,2,4,7,3,6,1},
                    {7,6,2,3,9,1,4,5,8},
                    {3,7,1,9,5,6,8,4,2},
                    {4,9,6,1,8,2,5,7,3},
                    {2,8,5,4,7,3,9,1,6}
                };

void * rowCheck(void* arg)
{
    int * row = (int *) arg;
    const char * result = "ok";

    for(int i = 0; i < 9; i++){
      int temp = row[i];
      int count = 0;

      for(int j = i; j < 9; j++){
        if(row[j] == temp || row[j] <= 0 || row[j] >= 10){
          count++; 
        }
        if(count > 1){
          result = "ko";
          pthread_mutex_lock(&mut1);
          std::cout<<"ERROR at "<< row[j]
            << " (row " << (row - arr[0])/9
              << " column " << j << ")" << std::endl;
          pthread_mutex_unlock(&mut1);
          break;
        }
      }
    }
    pthread_exit((void *) result);
}

int main()
{
  pthread_t id[9];

  pthread_mutex_init(&mut1, NULL);

  for (int i = 0; i != 9; ++i) {
    if (pthread_create(&id[i], NULL, &rowCheck, arr[i]) != 0) {
      std::cerr << "error when creating thread " << i << std::endl;
      return -1;
    }
  }

  for (int i = 0; i != 9; ++i) {
    void * retval;

    pthread_join(id[i], &retval);

    pthread_mutex_lock(&mut1);
    std::cout << i << ":" << (char *) retval << std::endl;
    pthread_mutex_unlock(&mut1);
  }

  return 0;
}

编译与执行:

/tmp % g++ -pedantic -Wextra -Wall c.cc -lpthread
/tmp % ./a.out
ERROR at 6 (row 1 column 1)
ERROR at 6 (row 1 column 6)
0:ok
1:ko
2:ok
3:ok
4:ok
5:ok
6:ok
7:ok
8:ok

另一种方法是通过分配给每个线程的 int 分配索引(并在线程中删除它):

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

pthread_mutex_t mut1;

int arr[9][9] = {  
                    {6,2,4,5,3,9,1,8,7},
                    {6,6,9,7,2,8,6,3,4},
                    {8,3,7,6,1,4,2,9,5},
                    {1,4,3,8,6,5,7,2,9},
                    {9,5,8,2,4,7,3,6,1},
                    {7,6,2,3,9,1,4,5,8},
                    {3,7,1,9,5,6,8,4,2},
                    {4,9,6,1,8,2,5,7,3},
                    {2,8,5,4,7,3,9,1,6}
                };

void * rowCheck(void* arg)
{
    int rowNum = *((int*) arg);

    delete (int*) arg;

    int * row = arr[rowNum];
    const char * result = "ok";

    for(int i = 0; i < 9; i++){
      int temp = row[i];
      int count = 0;

      for(int j = i; j < 9; j++){
        if(row[j] == temp || row[j] <= 0 || row[j] >= 10){
          count++; 
        }
        if(count > 1){
          result = "ko";
          pthread_mutex_lock(&mut1);
          std::cout<<"ERROR at "<< row[j]
            << " (row " << rowNum
              << " column " << j << ")" << std::endl;
          pthread_mutex_unlock(&mut1);
          break;
        }
      }
    }
    pthread_exit((void *) result);
}

int main()
{
  pthread_t id[9];

  pthread_mutex_init(&mut1, NULL);

  for (int i = 0; i != 9; ++i) {
    if (pthread_create(&id[i], NULL, &rowCheck, new int(i)) != 0) {
      std::cerr << "error when creating thread " << i << std::endl;
      return -1;
    }
  }

  for (int i = 0; i != 9; ++i) {
    void * retval;

    pthread_join(id[i], &retval);

    pthread_mutex_lock(&mut1);
    std::cout << i << ":" << (char *) retval << std::endl;
    pthread_mutex_unlock(&mut1);
  }

  return 0;
}

你问,

How can i synchronize these 9 threads so that they execute before main thread?

,我想你在谈论这些:

checkingRows is creating further 9 threads which are checking validity of each row.

当然,这些不能在main()之前运行,至少不能在main开始之前,除非你在那个时间框架。你不知道。但我认为您真正想要的只是他们 main 运行 超过某个点之前完成

嗯,这就是 pthread_join 的用途。我看到您已经在 main() 中为它启动的线程使用该函数,但您可能对这不会影响第二个线程启动的其他线程这一事实感到困惑。

它不会自动以这种方式工作。一旦启动,线程 运行 相互独立。如果你想等待一个线程完成,那么你必须加入那个特定的线程。在你的情况下,这可能意味着 checkingRows() 应该在它自己终止之前加入它启动的每个线程。