【问题标题】:Synchronization in multithreading多线程中的同步
【发布时间】:2019-09-07 15:37:19
【问题描述】:

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

我想检查大小为 9 的二维数组中行的有效性。每行应包含值(1 到 9)。 为此,我在主线程中创建了一个名为“void* checksRows(void* arg)”的线程,并将其与 main 连接。 然后线程检查行正在创建另外 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

【问题讨论】:

  • new intcout 的使用表明这是 C++,而不是 C。
  • 请注意,pthread_create(..., &amp;rowCheck, row); 中的 row 是一个指针,并且您向每个线程传递相同的指针,与 int 的值是否指向无关。
  • 与其使用 pthreads,我建议你看看 std::thread 这是可移植的内置线程库...
  • 您在main 中有retrun(而不是return
  • 在调用pthread_create(&amp;id1,NULL,&amp;checkingRows,NULL) 之后立即调用pthread_join(id1,NULL) 有什么意义?你为什么不直接打电话给checkintRows(NULL)呢?

标签: c++ multithreading operating-system mutex


【解决方案1】:

你问,

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

,我想你说的是这些:

checkingRows 正在创建另外 9 个线程,它们是 检查每一行的有效性。

当然,这些不能在main() 之前运行,至少不能在main 之前运行开始,除非你在那个时间范围内启动它们。你没有。但我认为你真正追求的是他们在main 超过某个点之前完成

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

它只是不会自动以这种方式工作。启动后,线程彼此独立运行。如果要等待线程完成,则必须加入该特定线程。在您的情况下,这可能意味着checkingRows() 应该在它本身终止之前加入它启动的每个线程。

【讨论】:

    【解决方案2】:

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

    相反,你不等待其他 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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-25
      • 2022-01-04
      • 1970-01-01
      • 1970-01-01
      • 2011-11-09
      • 2011-12-28
      相关资源
      最近更新 更多