在进行多线程编程时,我们总会遇到全局变量和数据结构的问题,这是多线程之间进行通信的问题。如果多个线程同时读写一个全局变量,那么会造成竞争或者出错。为了解决这一问题,我们需要对全局数据进行,使用互斥量实现锁的机制,当某个线程在某个操作前进行了加锁,那么某个操作只能在这个线程进行,直至将锁去除,相当于在这里将多线程的并行变成了串行。本文重点学习如何使用互斥量进行全局数据的同步,分为三个部分,第一部分给出代码示例,第二部分对代码进行讲解,第三部分给出运行结果。
一、代码示例
该程序使用4个线程实现两个向量的点积运算。
#include "StdAfx.h"
#include
#include
#include
typedef struct
{
double *a;
double *b;
double sum;
int veclen;
} DOTDATA;
#define NUMTHRDS 4
#define VECLEN 100000
DOTDATA dotstr;
pthread_t callThd[NUMTHRDS];
pthread_mutex_t mutexsum;
void *dotprod(void *arg)
{
int i, start, end, len ;
long offset;
double mysum, *x, *y;
offset = (long)arg;
len = dotstr.veclen;
start = offset*len;
end = start + len;
x = dotstr.a;
y = dotstr.b;
mysum = 0;
for (i=start; i
二、代码讲解
typedef struct
{
double *a;
double *b;
double sum;
int veclen;
} DOTDATA;
定义DOTDATA结构体,里面包含4个成员变量,可表示两个向量,乘积和向量的长度。
#define NUMTHRDS 4
#define VECLEN 100000
DOTDATA dotstr;
pthread_t callThd[NUMTHRDS];
pthread_mutex_t mutexsum;
定义全局变量和互斥量
int i, start, end, len ;
long offset;
double mysum, *x, *y;
offset = (long)arg;
len = dotstr.veclen;
start = offset*len;
end = start + len;
x = dotstr.a;
y = dotstr.b;
为了点积运算的方便,定义和使用一些局部变量
mysum = 0;
for (i=start; i
计算点积
pthread_mutex_lock (&mutexsum);
dotstr.sum += mysum;
printf("Thread %ld did %d to %d: mysum=%f global sum=%f\n",offset,start,end,mysum,dotstr.sum);
pthread_mutex_unlock (&mutexsum);
pthread_exit((void*) 0);
return(NULL);
给互斥量加锁,更新全局变量结构体中的数据,更新完成解锁,然后退出线程
a = (double*) malloc (NUMTHRDS*VECLEN*sizeof(double));
b = (double*) malloc (NUMTHRDS*VECLEN*sizeof(double));
for (i=0; i
给两个向量分配内存空间并赋值,然后给全局变量结构体中数据赋值,最后初始化互斥量
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
for(i=0;i
初始化所要执行的线程属性对象,并将其设置为可结合的,然后根据属性对象创建4个线程,执行 dotprod程序,并传递线程的ID
pthread_attr_destroy(&attr);
for(i=0;i
删除属性对象,然后结合线程,知道每个线程都结束才执行下一步程序
printf ("Sum = %f \n", dotstr.sum);
free (a);
free (b);
pthread_mutex_destroy(&mutexsum);
pthread_exit(NULL);
打印输出点积结果 ,释放两个向量的内存,删除互斥量,退出线程。
三、运行结果