1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

C言語 semaphore, mutexを使った並行プログラミングのサンプルコード

Posted at

はじめに

CSAPPを読んで、並行プログラミングの基礎を学んでいます。Mac環境だとサンプルコードを少しいじる必要があったので、メモとしてまとめます。

自分の環境です。

❯ sw_vers    
ProductName:    macOS
ProductVersion: 11.6
BuildVersion:   20G165

スレッドが同期エラーを起こすbadコード

badcnt.c
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

volatile long cnt = 0;

void *thread(void *vargp)
{
	long i;
	long niters = *((long *)vargp);

	for (i = 0; i < niters; i++)
	{
		cnt++;
	}
	return NULL;
}

int main(int argc, char **argv)
{
	long niters;
	pthread_t tid1, tid2;

	if (argc != 2) {
		printf("Usage: %s <niters>\n", argv[0]);
		exit(0);
	}
	niters = atoi(argv[1]);
	pthread_create(&tid1, NULL, thread, (void *)&niters);
	pthread_create(&tid2, NULL, thread, (void *)&niters);
	pthread_join(tid1, NULL);
	pthread_join(tid2, NULL);
	if (cnt != niters * 2)
		printf("BOOM! cnt = %ld\n", cnt);
	else
		printf("OK cnt=%ld\n", cnt);
	return 0;
}

### 実行結果

❯ gcc badcnt.c && ./a.out 1000000       
BOOM! cnt = 1011960

## mutexを使用して相互排他を行ったコード

goodcnt_mutex.c
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

volatile long cnt = 0;
pthread_mutex_t lock;

void *thread(void *vargp)
{
	long i;
	long niters = *((long *)vargp);

	for (i = 0; i < niters; i++)
	{
		pthread_mutex_lock(&lock);
		cnt++;
		pthread_mutex_unlock(&lock);
	}
	return NULL;
}

int main(int argc, char **argv)
{
	long niters;
	pthread_t tid1, tid2;

	pthread_mutex_init(&lock, NULL);
	if (argc != 2) {
		printf("Usage: %s <niters>\n", argv[0]);
		exit(0);
	}
	niters = atoi(argv[1]);
	pthread_create(&tid1, NULL, thread, (void *)&niters);
	pthread_create(&tid2, NULL, thread, (void *)&niters);
	pthread_join(tid1, NULL);
	pthread_join(tid2, NULL);
	if (cnt != niters * 2)
		printf("BOOM! cnt = %ld\n", cnt);
	else
		printf("OK cnt=%ld\n", cnt);
	return 0;
}

### 実行結果

❯ gcc goodcnt_mutex.c && ./a.out 1000000 
OK cnt=2000000

## セマフォを使用して相互排他を行ったコード

goodcnt_sem.c
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>

volatile long cnt = 0;
sem_t *mutex;

void *thread(void *vargp)
{
	long i;
	long niters = *((long *)vargp);

	for (i = 0; i < niters; i++)
	{
		sem_wait(mutex);
		cnt++;
		sem_post(mutex);
	}
	return NULL;
}

int main(int argc, char **argv)
{
	long niters;
	pthread_t tid1, tid2;

	mutex = sem_open("/mutex", O_CREAT, 0644, 1);
	if (argc != 2) {
		printf("Usage: %s <niters>\n", argv[0]);
		exit(0);
	}
	niters = atoi(argv[1]);
	pthread_create(&tid1, NULL, thread, (void *)&niters);
	pthread_create(&tid2, NULL, thread, (void *)&niters);
	pthread_join(tid1, NULL);
	pthread_join(tid2, NULL);
	if (cnt != niters * 2)
		printf("BOOM! cnt = %ld\n", cnt);
	else
		printf("OK cnt=%ld\n", cnt);
	return 0;
}

### 実行結果

❯ gcc goodcnt_sem.c && ./a.out 1000000
OK cnt=2000000

参考文献

CSAPP

1
0
0

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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?