LoginSignup
10
4

More than 5 years have passed since last update.

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

Last updated at Posted at 2017-02-17

知識

並列処理(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/
...

10
4
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
4