使用多个线程时保护全局变量

时间:2017-03-18 20:25:40

标签: c linux multithreading pthreads posix

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

目前,线程执行compute函数并更改“total”变量的顺序并不重要,但我想确保每个线程都不会更改全局变量,直到任何其他线程没有使用它为止。

如果有人能指出我应该如何实现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

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分: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执行计算功能并且锁是空闲的,它将获取锁,增加总数,然后释放锁。如果线程T2T1具有锁定时调用计算,则T2将无法继续超出代码中的该点,并将等待{{1}释放锁资源}。因此它保护全局变量;当一个线程持有锁时,希望改变共享变量的线程无法同时执行此操作。