Edited at

様々な言語における並行、並列処理(C,C++編)

More than 1 year has passed since last update.


知識

並列処理(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;
}


このようにすれば値破壊は起こらない。


引用: https://ota42y.com/blog/2015/06/18/c-thread/

...