【问题标题】:Safely modifying variable in two threads在两个线程中安全地修改变量
【发布时间】:2021-03-17 09:42:30
【问题描述】:

考虑以下人为的例子-

假设我有一个修改全局变量的线程:

void thread_1(void* param) {
    for (int i=0; i<10; i++) {
        x += i; // x is global.
    }
}

假设我有另一个线程修改相同的全局变量:

void thread_2(void* param) {
    while (1) {
        x = 0; // x is global.
        usleep(20000);
    }
}

如何暂停第二个线程的执行以等待第一个线程完成执行以安全地在第二个线程中继续执行以防止发生争用条件?

【问题讨论】:

标签: c windows unix thread-safety pthreads


【解决方案1】:

如果你想创建线程,例如 6 个线程,你不需要像你那样使用 6 个函数,void thread1 和 thread2。你必须像这样创建它们:

pthread_mutex_t lock= PTHREAD_MUTEX_INITIALIZER;   // this locks the critical arrea
pthread_cond_t  consum = PTHREAD_COND_INITIALIZER; // and this is a conditional variable
    pthread_t consumerN[2];
    
    //then in your main function 
    int main(){
           
          
          pthread_create(&consumerN[1],NULL,thread_1,NULL);// go to thread_1
          pthread_create(&consumerN[2],NULL,thread_2,NULL);//go to thread_2
           
    }
    void thread_1(int *param){
       pthread_mutex_lock(&lock);
       pthread_cond_wait(&consum,lock);
       for (int i=0; i<10; i++) {
           x += i; // x is global.
      }
      pthread_mutex_unlock(&lock);
   }
   void thread_2(int *param){
       pthread_mutex_lock(&lock);
       pthread_cond_wait(&consum,lock);
       
      while(1){
          x=0;
          sleep(2000);


      }
      pthread_mutex_unlock(&lock);
  }

【讨论】:

  • thread_2thread_1 以不同方式修改 x 变量,这就是我使用两个不同线程的原因。您能否提供一个示例,其中两个修改x 的线程以不同的方式使用锁?还有如何使用 windows/winsock api 来实现这一点?
  • @daskin_i334 我给你两个简单的例子来使用锁,我没有从你的代码中得到足够的信息但是如果你使用两个不同的函数来修改变量 x 为什么你需要锁? thread_1 和 thread_2 是函数而不是线程你怎么知道你所说的许多线程同时运行相同的区域?给我更多信息
  • 它们只是人为的例子,我需要知道如何在两个线程中安全地修改一个变量而没有关键的竞争条件。我只是确保我可以将您的原始答案应用于thread_1thread_2,并且没有误会或误解。
  • @daskin_i334 再次检查我编辑我写的内容,希望这对你更有帮助
  • 你知道哪些 windows/winsock api 做同样的逻辑吗?
【解决方案2】:

您需要添加互斥锁。当一个互斥锁尝试在关键区域运行时,另一个必须等​​待。创建一个停止线程的互斥锁

pthread_mutex_t lock= PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t  consum = PTHREAD_COND_INITIALIZER;

void function(){ //were the mutex is trying to run 
 pthread_mutex_lock(&lock);
 pthrad_cond_wait(&consum,lock);// this is saying  that : only one at a time
 
  //critical area


  //here you can use signals to let the other threads when this current thread is funish.
  pthread_mutex_unlock(&lock);// when a thread unlock's the  mutex then the other starting to run the critical area

}

【讨论】:

  • 这是否适用于执行相同功能的多个线程?我应该将锁添加到两个线程还是只添加一个?
  • @daskin_i334 是的!
  • @daskin_i334 再次检查我忘记在关键区域添加条件
  • 您介意将此方法应用于我上面的示例以提高可读性吗?
  • @daskin_i334 在我的例子中我说 // 关键区域你必须把你的 for 循环或 while 循环放在那里
猜你喜欢
  • 2017-10-05
  • 1970-01-01
  • 2013-09-28
  • 1970-01-01
  • 2012-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-27
相关资源
最近更新 更多