【问题标题】:Protecting global variable when using multiple threads使用多个线程时保护全局变量
【发布时间】:2017-08-10 07:20:54
【问题描述】:

我在 linux 中编写的 C 程序创建了多个线程(在本例中为 8 个),每个线程都应运行函数 compute(),这将使全局变量“total”增加 1000。该程序当前按预期工作这方面,因为它输出的最终总数为 8000。

目前线程执行计算函数和更改“总”变量的顺序无关紧要,但我想确保每个线程在没有被任何其他线程使用之前不会更改全局变量.

如果有人能指出我应该如何实现 POSIX 信号量来实现这一目标的正确方向,那将不胜感激,因为这个领域/线程一般对我来说是新的。

程序的当前代码如下。 非常感谢!

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <pthread.h>
#include <sys/types.h>
#include <unistd.h>
#include <semaphore.h>

#define N 8 /* define the total number of processes we want */
/* Set global variable */
float total=0;

/* compute function just does something. */
int compute()
{
  int i;
  float oldTotal =0, result =0;

  /*for a large number of times just square root and square the arbitrary number 1000*/
  for (int i = 0; i < 2000000000; i++)  //Arbitrary number to allow process to run for a while.
      {
        result = sqrt(1000.0)*sqrt(1000.0);
      }

  /*Print the result - should be no suprise*/
  printf("Result is %f\n", result); 

  /*We want to keep a running total in the global variable total*/
  oldTotal = total;   
  total = oldTotal + result;

  /*Print the running total so far*/
  printf("Total is %f\n", total);
  return(0);
}


void* thread_procedure(void* param)
{

    int i = (int)param;
    /* give a message about the proc ID */
    printf("Process Id for process %d is %d\n",i,getpid());
    /* call the function to do some computation. If we used sleep
    The process would simply sleep. We do not want that */

    compute(); 

    return NULL;
}


int main()
{
  int i, j;
  sem_init(&mutex, 0, 1); //Initialise mutex 
  pthread_t thread[N];   //Array of threads, N number of processes     


  printf("\n"); /* bit of whitespace */
  /* We want to loop to create the required number of processes
  Note carefully how only the child process is left to run */
  for(i=0;i<N;i++)
    {
      /* start new thread and catch it if it/one fails */
      j = pthread_create(&thread[i], NULL, &thread_procedure, (void*)i);
      if (j)
          {
            printf("Error");
            exit(1);
          }
    }


  /* joining with threads */
  for(i=0;i<N;i++)
       {
          pthread_join(thread[i], NULL);
       }

  sem_destroy(&mutex); 
  /* nothing else to do so end main function (and program) */
  return 0;
} // end function: main

【问题讨论】:

标签: c linux multithreading pthreads posix


【解决方案1】:

如果我可以建议使用 pthread mutex 也可以实现对共享变量的互斥,下面的示例就可以完成。您尝试完成的工作可能会更快。

#include <pthread.h>

//Shared global variable
float total = 0;

//Shared lock
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; 

//some thread function that adds 1,000 to total one thread at a time
void *compute(){

    //If no thread is using the lock, acquire lock and add 1,000 to total. The lock prevents other threads from executing this piece of code during a context switch. 
    pthread_mutex_lock(&lock);
    total += 1000;
    //Release lock
    pthread_mutex_unlock(&lock);

    return NULL;

}

这样,如果线程T1执行计算函数并且锁是空闲的,它会获取锁,增加total,然后释放锁。如果线程T2T1 拥有锁的情况下调用计算,T2 将无法继续超出代码中的该点,并将等待T1 释放锁资源。因此它保护了全局变量;当一个线程持有锁时,希望改变共享变量的线程不能同时这样做。

【讨论】:

  • 谢谢,我选择了这个解决方案!
【解决方案2】:

听起来你需要使用互斥锁或信号量

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-16
    • 2021-12-27
    • 1970-01-01
    • 2013-02-07
    • 2013-11-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多