【问题标题】:Synchronizing threads in the order using mutexes使用互斥锁按顺序同步线程
【发布时间】:2016-06-21 20:14:30
【问题描述】:

我有这个 C 程序,它必须按 0-6 的顺序显示线程。我正在使用互斥锁,但是当我尝试运行我的代码时,什么也没有发生,什么也没有显示。此外,编译器没有显示错误

我使用了锁定和解锁互斥锁,但我不确定我是否在正确的位置创建了它。 任何建议和帮助表示赞赏。

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <time.h>


void *text(void *arg);
long code[] = { 4, 6, 3, 1, 5, 0, 2 }; // Order in which to start         threads
int num = 0;

pthread_mutex_t a_mutex = PTHREAD_MUTEX_INITIALIZER;


int main()
{
int i;
pthread_t tid[7];
// Initialize random number generator
time_t seconds;
time(&seconds);
srand((unsigned int) seconds);

int rc;



// Create our threads
for (i = 0; i < 7; i++)
{
    pthread_create(&tid[i], NULL, text, (void*)code[i]);

    for (i = 0; i < 7; i++)

    {  rc = pthread_mutex_lock(&a_mutex);

        for (i = 0; i < 7; i++)
        {
             rc = pthread_mutex_unlock(&a_mutex);
        }
    }

}
//join threads
for (i=0; i<7; i++)
{
    if (pthread_join(tid[i], NULL));
                }

rc = pthread_mutex_destroy(&a_mutex);

// Exit main
return 0;

}
void *text(void *arg)
{
long n = (long)arg;
int rand_sec = rand() % (3 - 1 + 1) + 1; // Random num seconds to     sleep
while (num != n) {} // Busy wait used to wait for our turn
num++; // Let next thread go
sleep(rand_sec); // Sleep for random amount of time
printf("This is thread %d.\n", n);
// Exit thread
pthread_exit(0);
}

【问题讨论】:

    标签: c multithreading synchronization pthreads mutex


    【解决方案1】:

    找出问题的关键是问自己一个问题“我的 6 个线程之间共享的数据是什么?” 是在锁定的互斥块中需要互斥保护(读取和写入)的变量。目前,您只是从单个主线程锁定和解锁互斥锁,这实际上什么都不做。

    你可能想要更接近这个的东西(尽管这可以大大简化 - 例如你可以完全移除睡眠):

    #include <stdlib.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <pthread.h>
    #include <time.h>
    
    void *text(void *arg);
    long code[] = { 4, 6, 3, 1, 5, 0, 2 }; // Order in which to start threads
    int num = 0;
    
    pthread_mutex_t a_mutex = PTHREAD_MUTEX_INITIALIZER;
    
    int main()
    {
        int i;
        pthread_t tid[7];
        // Initialize random number generator
        time_t seconds;
        time(&seconds);
        srand((unsigned int) seconds);
        // Create our threads
        for (i = 0; i < 7; i++)
            pthread_create(&tid[i], NULL, text, (void*)code[i]);
    
        //join threads
        for (i=0; i<7; i++)
            if (pthread_join(tid[i], NULL));
    
        pthread_mutex_destroy(&a_mutex);
    
        // Exit main
        return 0;
    }
    
    void *text(void *arg)
    {   
        long n = (long)arg;
        long localNum = -1;
        int rand_sec = rand() % (3 - 1 + 1) + 1; // Random num seconds to     sleep
        int rc;
        while ( localNum != n )
        {
            rc = pthread_mutex_lock(&a_mutex);
            localNum = num;
            rc = pthread_mutex_unlock(&a_mutex);
            sleep(rand_sec); // Sleep for random amount of time
        }
    
        printf("This is thread %d.\n", n);
    
        rc = pthread_mutex_lock(&a_mutex);
        num++; // Let next thread go
        rc = pthread_mutex_unlock(&a_mutex);
    
        pthread_exit(0);
    }
    

    【讨论】:

      【解决方案2】:

      这是代码的最小版本,删除了等待和随机化部分,因为它们会转移人们对锁如何工作的注意力。

      线程自动排队等待互斥锁。

      您需要在例程函数中请求锁。

      永远记得关闭线程并释放所有可能的代码路径上的锁。

      #include <stdlib.h>
      #include <stdio.h>
      #include <unistd.h>
      #include <pthread.h>
      #include <time.h>
      
      
      void *text(void *arg);
      long code[] = { 4, 6, 3, 1, 5, 0, 2 }; // Order in which to start         threads
      int num = 0;
      
      pthread_mutex_t a_mutex = PTHREAD_MUTEX_INITIALIZER;
      
      
      int main()
      {
      int i;
      pthread_t tid[7];
      
      // Create our threads
      for (i = 0; i < 7; i++)
      {
          pthread_create( &tid[i], NULL, text, (void*) & code[i] );
      }
      
      
      
      //join threads
      for (i=0; i<7; i++)
      {
          pthread_join(tid[i], NULL);
      }
      
      pthread_mutex_destroy( & a_mutex );
      
      // Exit main
      return 0;
      }
      
      void *text(void *arg)
      {
      while(1){
          pthread_mutex_lock(&a_mutex);
          if (num == *(int *) arg){
              printf("This is thread has the code %d\n",*(int *) arg);
              num++;
              pthread_mutex_unlock(&a_mutex);
              pthread_exit(0);
              }
          pthread_mutex_unlock(&a_mutex);
          }
      }
      

      【讨论】:

        【解决方案3】:

        @Anastasia Netz。您只需要在代码的关键部分使用pthread_mutex_lock and pthread_mutex_unlock 互斥锁,而不仅仅是在主线程中。请在您的代码中仔细识别您的关键部分(完成一项重要工作并且对所有正在执行的线程都通用但只有其中一个可以访问的部分)并在那里使用这些互斥锁。 现在让我解释一下你的代码: 在您的代码中,您只是创建了七个线程。在创建每个线程之后,您只需将互斥锁锁定一次并无缘无故地解锁七次。因此,在完成所有七次迭代(for 创建这七个线程)之后,您已将互斥锁锁定了七次,并且将其解锁了 (7*7=49) 四十九次。 这是完成这项工作的代码:

        for (i = 0; i < 7; i++) { pthread_create(&tid[i], NULL, text, (void*)code[i]);

         for (i = 0; i < 7; i++)
         {  
         rc = pthread_mutex_lock(&a_mutex);
        
            for (i = 0; i < 7; i++)
            {
                 rc = pthread_mutex_unlock(&a_mutex);
            }
        }}
        

        请查看 Xvan 的代码。

        【讨论】:

          猜你喜欢
          • 2014-05-02
          • 1970-01-01
          • 1970-01-01
          • 2021-06-04
          • 2020-12-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-06-10
          相关资源
          最近更新 更多