##知識
並列処理(Parallel)と並行処理(Concurrent)
-
並行: 1CPU,マルチスレッド(同期)
-
並列: マルチCPU(非同期)
-
排他制御: あるデータに対し、特定スレッド内での処理が終わる前に、他のスレッドからアクセスできないようにする。
##実験
一度の命令でアクセスできない64bit整数型の変数を複数スレッドからアクセスしてみる
pthread_test
#include "pthread.h"
#include <stdio.h>
void *func(void *p){
printf("Passed: %d",*(short*)p);
}
int main(void){
pthread_t pthread;
short val = 2525;
pthread_create(&pthread,NULL,&func,&val);
pthread_join(pthread,NULL);
printf("MAIN FINISHED");
return 0;
}
pthreadsで簡単にマルチスレッド。
32bitCPUでLONGLONG型(64bit)に複数スレッドからアクセスしようとすると…
longlongbreak
#include "pthread.h"
#include <stdio.h>
#define REPEAT 5000000
long long int a = 0;
void check(){
if(a != 1 && a != -1){
printf("LONG LONG VALUE HAS BROKEN!!!");
}
}
void *func(){
int i;
for(i=0;i<REPEAT;i++){
a=1;
check();
}
printf("SUB FINISHED");
}
int main(void){
pthread_t pthread;
pthread_create(&pthread,NULL,&func,NULL);
int i;
for(i=0;i<REPEAT;i++){
a=-1;
check();
}
pthread_join(pthread,NULL);
printf("MAIN FINISHED");
return 0;
}
結果:
LONG LONG VALUE HAS BROKEN!!!SUB FINISHEDMAIN FINISHED
私の環境ではREPEAT回数を5000000回にした辺りから、値の破壊が発生する。
これは32BITCPUでは、一度の命令では64bit型データにアクセスできないからである。
これを防ぐために排他制御が必要。
排他制御を行うには、mutexを使う。
mutex
#include "stdio.h"
#include "pthread.h"
#define REPEAT 50000000
pthread_mutex_t mutex;
long long int a = 0;
void check(){
if(a != -1 && a != 1){
printf("LOG LONG HAS BROKEN!");
}
}
void *func_thread() {
int i=0;
for(i=0; i < REPEAT; i++){
pthread_mutex_lock(&mutex);
a = 1;
check();
pthread_mutex_unlock(&mutex);
}
printf("SUB FINISH");
}
int main(void) {
pthread_mutex_init(&mutex, NULL);//mutexオブジェクト初期化
pthread_t pthread;
pthread_create( &pthread, NULL, &func_thread,NULL);
int i=0;
for(i=0; i < 10000; i++){
pthread_mutex_lock(&mutex);
a =-1;
check();
pthread_mutex_unlock(&mutex);
}
pthread_join(pthread, NULL);
pthread_mutex_destroy(&mutex);//mutexオブジェクト破棄
printf("MAIN FINISH");
return 0;
}
このようにすれば値破壊は起こらない。