Pthread - whdlgp/system_programming_pra GitHub Wiki

POSIX thread

๋ญ ๋งํ•˜์ž๋ฉด ํ‘œ์ค€ ์“ฐ๋ž˜๋“œ. ์œ ๋‹‰์Šค ๊ณ„์—ด ์šด์˜์ฒด์ œ์—์„œ๋Š” ํฌํ•จ๋œ๋‹ค๊ณ  ํ•œ๋‹ค. ์œˆ๋„์šฐ์ฆˆ ์šฉ์œผ๋กœ๋„ ์žˆ๋‹ค๊ณ  ํ•˜๋Š”๋ฐ, ์จ๋ณธ์ ์€ ์—†๋‹ค.
๊ทธ๋™์•ˆ RTOS๋ฅผ ์“ฐ๋ฉด์„œ, ์“ฐ๋ž˜๋“œ๋Š” ๋ฌดํ•œ๋ฃจํ”„๋ฅผ ํฌํ•จํ•ด์•ผ ํ•œ๋‹ค๋Š” ์ƒ๊ฐ์„ ๊ฐ€์ง€๊ณ  ์žˆ์—ˆ๋Š”๋ฐ, POSIX thread ๋˜ํ•œ ๋ฌดํ•œ๋ฃจํ”„๋Š” ํ•„์ˆ˜๊ฐ€ ์•„๋‹Œ ๋ชจ์–‘์ด๋‹ค. ์•ฝ๊ฐ„ ๊ดด๋ฆฌ๊ฐ์ด ์žˆ๊ธด ํ–ˆ์ง€๋งŒ ์ผ๋ฐ˜ ํŽŒ์›จ์–ด ๋ ˆ๋ฒจ์—์„œ๋Š” main๋‚ด๋ถ€์— ๋ฌดํ•œ๋ฃจํ”„๊ฐ€ ์žˆ๋Š”๊ฑธ ์ƒ๊ฐํ•˜๋ฉด ์ดํ•ด๋Š” ๋œ๋‹ค.

์“ฐ๋ž˜๋“œ ์ƒ์„ฑ๊ณผ ์ข…๋ฃŒ, ์ •๋ฆฌ

์ƒ์„ฑ

pthread_create(์“ฐ๋ž˜๋“œ ID๋ฅผ ์ €์žฅํ•  ๋ณ€์ˆ˜ ํฌ์ธํ„ฐ, ์†์„ฑ, ๋Œ๋ฆด ํ•จ์ˆ˜(๋‚ด์šฉ๋ฌผ), ์“ฐ๋ž˜๋“œ์— ๋„˜๊ฒจ์ค„ ์ธ์ž);
  • ์ฒซ๋ฒˆ์งธ ์ธ์ž : ์“ฐ๋ž˜๋“œ์˜ ID๋ฅผ ์ €์žฅํ•  ๋ณ€์ˆ˜์˜ ํฌ์ธํ„ฐ ๊ฐ’์ด ๋“ค๋ฆฌ์–ด๊ฐ„๋‹ค. ๋ณ€์ˆ˜๋Š” pthread_t ๋กœ ์„ ์–ธํ•˜๋ฉด ๋œ๋‹ค.
  • ๋‘๋ฒˆ์งธ ์ธ์ž : ์†์„ฑ๊ฐ’์ด ๋“ค์–ด๊ฐ€๋Š”๋ฐ, ์ฃผ๋กœ NULL๊ฐ’์ด ๋“ค์–ด๊ฐ„๋‹ค.
  • ์ƒˆ๋ฒˆ์งธ ์ธ์ž : ์“ฐ๋ž˜๋“œ์—์„œ ์‹คํ–‰๋  ๋‚ด์šฉ๋ฌผ์ด ์ž‘์„ฑ๋œ ํ•จ์ˆ˜์˜ ํฌ์ธํ„ฐ๋ฅผ ๋„ฃ์–ด์ค€๋‹ค. ์ด๋•Œ ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜๊ฐ’์€ void ํ˜•์ด ์•„๋‹Œ void* ๋‹ค.
  • ๋‚ด๋ฒˆ์งธ ์ธ์ž : ์“ฐ๋ž˜๋“œ์—์„œ ์‹คํ–‰ํ•  ํ•จ์ˆ˜์—์„œ ์ธ์ž๋กœ ์ „๋‹ฌ๋œ๋‹ค.

์ •์ƒ์ ์œผ๋กœ ์“ฐ๋ž˜๋“œ๊ฐ€ ์ƒ์„ฑ๋˜๋ฉด 0์„ ๋ฆฌํ„ดํ•œ๋‹ค.

์ข…๋ฃŒ

pthread_exit(๋ฆฌํ„ด๊ฐ’);

์“ฐ๋ž˜๋“œ ๋‚ด๋ถ€์—์„œ ์“ฐ๋ž˜๋“œ๋ฅผ ์ข…๋ฃŒํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ํ•จ์ˆ˜๋‹ค. ๋ช‡๊ฐ€์ง€ ํŠน์ง•์„ ๋“ค๋ฉด

  • ํ˜ธ์ถœ๋œ ์“ฐ๋ž˜๋“œ๋งŒ ์ข…๋ฃŒํ•œ๋‹ค. ๋‹ค๋ฅธ ์“ฐ๋ž˜๋“œ์—๋Š” ์˜ํ–ฅ์ด ์•ˆ๊ฐ„๋‹ค.
  • return๊ณผ ๋‹ค๋ฅด๊ฒŒ ๋™์ ํ• ๋‹น์ด ๋‚ด๋ถ€์ ์œผ๋กœ ์ด๋ฃจ์–ด์ง„๋‹ค.

์–ด๋–ป๊ฒŒ ๋ณด๋ฉด main๋ฌธ๋„ ํ•˜๋‚˜์˜ ์“ฐ๋ž˜๋“œ๋กœ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์˜ˆ๋กœ main์—์„œ return์œผ๋กœ ์ข…๋ฃŒ์‹œ ๋‹ค๋ฅธ ์“ฐ๋ž˜๋“œ๋“ค์€ ๋ณ„๋„์˜ ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ํ˜ธ์ถœํ•  ์‹œ๊ฐ„๋„ ์—†์ด ์ข…๋ฃŒ๋˜๋ฒ„๋ฆฐ๋‹ค. ๋•Œ๋ฌธ์— ๊ทธ๋Ÿฐ๊ฑธ ๋ง‰๊ธฐ ์œ„ํ•ด pthread_exit๋ฅผ ์“ด๋‹ค๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค.
return๊ณผ ๋‹ค๋ฅด๊ฒŒ ์–ด๋”˜๊ฐ€ ๋™์ ํ• ๋‹น์„ ํ•˜๋Š”๋ฐ, ๋‚˜๋Š” ์ •ํ™•ํžˆ ๋ญ˜ ๋™์ ํ• ๋‹น ํ•˜๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ๋‹ค ใ…กใ…ก;. ์–ด์จŒ๋“  ์“ฐ๋ž˜๋“œ๋ฅผ ๋งŽ์ด ์ƒ์„ฑํ•ด๋„ ์ด ๋™์ ํ• ๋‹น๋œ ์ „์ฒด ์–‘์€ ๋ณ€ํ™”ํ•˜์ง€ ์•Š๋Š”๋‹ค๊ณ . ๊ทธ๋ฆฌ๊ณ  ๋™์ ํ• ๋‹น์„ ํ•ด์žฌํ•˜์ง€ ์•Š๊ณ  ๋‚จ๊ฒจ๋‘๋Š”๋ฐ, ์–ด์ฐจํ”ผ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ฃฝ์œผ๋ฉด ๋‹ค ์ •๋ฆฌ๋ ๊บผ๊ธฐ ๋•Œ๋ฌธ์ด๋ž€๋‹ค. (์ฒญ์†Œ ์•„์ฃผ๋จธ๋‹ˆ๊ฐ€ ๋ฌผ ๋‚ด๋ ค์ฃผ์‹คํƒ ๋Œ€ ๋‚ด๊ฐ€ X์„ ๋‚ด๋ฆด ํ•„์š”๊ฐ€ ์žˆ๋Š”๊ฐ€? ๋ผ๊ณ  ์ƒ๊ฐํ•˜๋Š”๊ฑด๊ฐ€,,,)

์ •๋ฆฌ

pthread_join(์“ฐ๋ž˜๋“œ ID๋ฅผ ์ €์žฅํ•œ ๋ณ€์ˆ˜, ๋ฆฌํ„ด๋œ ๊ฐ’์„ ์ €์žฅํ•  ๋ณ€์ˆ˜ ํฌ์ธํ„ฐ);

fork๋œ ์ž์‹ ํ”„๋กœ์„ธ์Šค๋ฅผ waitpid๋กœ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๊ฒƒ๊ณผ ๊ฝค ๋น„์Šทํ•˜๋‹ค. ์ง€์ •ํ•œ ์“ฐ๋ž˜๋“œ ID๋ฅผ ๊ฐ€์ง„ ์“ฐ๋ž˜๋“œ๊ฐ€ ์ข…๋ฃŒ๋˜๋Š”๊ฒƒ์„ ๊ธฐ๋‹ค๋ฆฐ๋‹ค. ๊ธฐ๋‹ค๋ฆฌ๋Š” ์“ฐ๋ž˜๋“œ ์ชฝ์—์„œ return ์ด๋‚˜ pthread_exit ํ•จ์ˆ˜๋กœ ๋ฐ˜ํ™˜ํ•œ ๊ฐ’์€ ๋‘๋ฒˆ์งธ ์ธ์ž์— ๋„ฃ์–ด์ค€ ํฌ์ธํ„ฐ์˜ ๋ณ€์ˆ˜๊ฐ€ ๋„˜๊ฒจ๋ฐ›๋Š”๋‹ค.

pthread_detach(์“ฐ๋ž˜๋“œ ID๋ฅผ ์ง€์ •ํ•œ ๋ณ€์ˆ˜);

๋งŒ์•ฝ ์ง€์ •ํ•œ ์“ฐ๋ž˜๋“œ ID๋ฅผ ๊ฐ€์ง„ ์“ฐ๋ž˜๋“œ๊ฐ€ detached ์†์„ฑ์ด๋ผ๋ฉด main์ชฝ์—์„œ ์“ฐ๋ž˜๋“œ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๋Š”๋‹ค. detached ์†์„ฑ์˜ ์“ฐ๋ž˜๋“œ๋Š” detach ํ˜ธ์ถœ์ด ๋˜๋ฉด, ์“ฐ๋ž˜๋“œ๋ฅผ ์ข…๋ฃŒํ•  ๋•Œ๊ฐ€ ๋˜์—ˆ์„ ๋•Œ ์ž๊ธฐ๊ฐ€ ์•Œ์•„์„œ ๋ชจ๋“  ์ž์›์„ ํ•ด์ œํ•œ๋‹ค. (์ž์œ ๋ฐฉ์ž„์ฃผ์˜?)
๋ง‰์ƒ ์“ฐ๋ ค๋‹ˆ ์ด๊ฑด ๋ณ„๋กœ ์“ฐ์ง€ ์•Š๋Š”๊ฒƒ ๊ฐ™๊ธฐ๋„,,,

์ด์ •๋„๋งŒ ์•Œ์•„๋„ ์“ฐ๋ž˜๋“œ์˜ ๊ธฐ๋ณธ์ ์ธ ์‚ฌ์šฉ๋ฒ•์€ ์•„๋Š” ๊ฒƒ์ด ์•„๋‹๊นŒ. ๋ช‡๊ฐ€์ง€ ์˜ˆ์ œ๋กœ ์ข€ ์ต์ˆ™ํ•ด์ ธ ๋ณด๊ธฐ๋กœ ํ•˜์ž.

/practice8/ex8.c

๋Œ€์ถฉ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์“ฐ๋ฉด ๋œ๋‹ค. ๋„˜๊ฒจ์ค„ ์ธ์ž๊ฐ€ ์ •์ˆ˜ 5๋ผ๋ฉด,

#include <pthread.h>
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>

void *thread(void* data);

int main(void)
{
	pthread_t threads[5];
	int rc, t;

	for(t = 0; t < 5; t++)
	{
		printf("In main: creating thread %d\n", t);
		rc = pthread_create(&threads[t], NULL, thread, (void*)&t);
		sleep(1); //์“ฐ๋ž˜๋“œ์ชฝ์—์„œ ์ธ์ž๋ฅผ ๋ฐ›์„ ์‹œ๊ฐ„์„ ์ถฉ๋ถ„ํžˆ ์ฃผ๊ธฐ
		
		if(rc) //์—๋Ÿฌ์ฒ˜๋ฆฌ
		{
			printf("Thread creation error!\n");
			exit(1);
		}
	}

	pthread_exit(NULL);
	
	return 0;
}

void *thread(void* data)
{
	int id = *(int*)data;
	sleep(id);
	static int cnt = 0;
	//printf("Hello I'm thread number %d \n", id);
	printf("Hello I'm thread number %d, (cnt = %d)\n",id, cnt++); 
	pthread_exit(NULL);
}

์œ„ ์˜ˆ์ œ์—์„œ๋Š” ์„œ๋กœ๋‹ค๋ฅธ 5๊ฐœ์˜ ์“ฐ๋ž˜๋“œ๊ฐ€ ๊ฐ™์€ ๋‚ด์šฉ์˜ ์ผ์„ ํ•˜๋„๋ก ํ•˜์˜€๋‹ค. ์†์„ฑ๊ฐ’์€ ์–ด์ง€๊ฐ„ํ•ด์„  ๋ฐ”๊ฟ€ ์ผ์ด ์—†์—ˆ๊ธฐ ๋•Œ๋ฌธ์— NULL ๊ฐ’์œผ๋กœ ์ƒ์„ฑ์„ ํ•œ๋‹ค.
์“ฐ๋ž˜๋“œ์— ์ธ์ž๊ฐ€ ์ „๋‹ฌ๋  ๋•Œ ์•ฝ๊ฐ„์˜ ์‹œ๊ฐ„์„ ์ฃผ์–ด์•ผ ํ•œ๋‹ค๊ณ  ํ•œ๋‹ค. ์•ˆ๊ทธ๋Ÿฌ๋ฉด ์ œ๋Œ€๋กœ ์ „๋‹ฌ์ด ์•ˆ๋œ๋‹ค๊ณ ,,,

In main: creating thread 0
Hello I'm thread number 0, (cnt = 0)
In main: creating thread 1
In main: creating thread 2
Hello I'm thread number 1, (cnt = 1)
In main: creating thread 3
In main: creating thread 4
Hello I'm thread number 2, (cnt = 2)

์‹คํ–‰ํ•ด๋ณด๋ฉด ์ธ์ž๊ฐ€ ์ œ๋Œ€๋กœ ์ „๋‹ฌ ๋จ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

/practice9/ex9.c

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

void* thread(void* data)
{
	int num = *(int*)data;
	printf("num %d\n", num);
	sleep(10);

	return (void*)(num*num);
}

int main(void)
{
	pthread_t th;
	int tid;
	int status;
	int a = 100;

	tid = pthread_create(&th, NULL, thread, (void*)&a);
	pthread_join(th, (void*)&status);
	printf("Thread join: %d\n", status);

	return 0;
}

์ด๋ฒˆ์—” ๊ฐ„๋‹จํ•œ ์˜ˆ์ œ์— pthread_join์„ ์ด์šฉํ•ด๋ดค๋‹ค. ์ƒ์„ฑ๋˜๋ฉด์„œ ์ธ์ž๋กœ 100์„ ๋„˜๊ฒจ๋ฐ›๊ณ , 100*100์„ ํ•˜์—ฌ returnํ•œ๋‹ค.
์ด๋ฒˆ์—” pthread_exit๋ฅผ ์ด์šฉํ•˜์ง€ ์•Š์•˜๋Š”๋ฐ, ์ด์šฉํ•˜์ง€ ์•Š์•„๋„ ๋ฐ˜ํ™˜์ด ์ž˜ ๋˜๋Š”๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ์„ฑ๋Šฅ ์ฐจ์ด๊ฐ€ ํฌ๊ฒŒ ๋‚˜๋Š”์ง€๋Š” ๋ชจ๋ฅด๊ฒ ๊ณ ,,, ์“ฐ๋ž˜๋“œ๋ฅผ ์—ฌ๋Ÿฌ๊ฐœ ์ƒ์„ฑํ•˜๋ฉด ๋Š๊ปด์งˆ ์ง€ ๋ชจ๋ฅด๊ฒ ๋‹ค.
return๋œ ๊ฐ’์€ pthread_join์„ ์ด์šฉํ•ด์„œ status ๋ผ๋Š” ๋ณ€์ˆ˜์— ์ €์žฅํ›„ printf๋กœ ์ถœ๋ ฅํ•œ๋‹ค.

num 100
Thread join: 10000

์“ฐ๋ž˜๋“œ ์†์„ฑ

์•ž์„œ pthread_create ์˜ ์†์„ฑ ์ž๋ฆฌ์— NULL๊ฐ’์€ ๊ธฐ๋ณธ์ด๋ผ๊ณ  ํ–ˆ๋Š”๋ฐ, ์†์„ฑ์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.
์†์„ฑ์€ ๋‹ค์Œ ๋‘๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค.

  • PTHREAD_CREATE_JOINABLE
  • PTHREAD_CREATE_DETACHED

NULL์„ ๋„ฃ์„ ๊ฒฝ์šฐ ๊ธฐ๋ณธ์€ JOINABLE์ด๋‹ค. ๊ทธ ์ด์™ธ์— ์†์„ฑ๋„ ์žˆ๋Š”๋“ฏ ํ•˜์ง€๋งŒ(์œ ์ € ๋ชจ๋“œ ์“ฐ๋ž˜๋“œ์ธ์ง€ ์ปค๋„ ๋ชจ๋“œ ์“ฐ๋ž˜๋“œ์ธ์ง€ ๋“ฑ๋“ฑ,,,), ๊ตณ์ด ์†์„ฑ์„ ๋ฐ”๊ฟ€ ํ•„์š”๊ฐ€ ์žˆ๋‹ค๋ฉด ์•„๋งˆ ์œ„์˜ ์†์„ฑ์„ ์ฃผ๋กœ ๋ฐ”๊พธ์ง€ ์•Š์„๊นŒ.

์“ฐ๋ž˜๋“œ ์†์„ฑ ์ดˆ๊ธฐํ™”

pthread_attr_init(์†์„ฑ ์ž๋ฃŒํ˜• ํฌ์ธํ„ฐ)

์—ฌ๊ธฐ์„œ ์ž๋ฃŒํ˜•์ด๋ผ๊ณ  ํ•œ ๊ฒƒ์ด, ์ €๊ธฐ ์ž๋ฆฌ์— ์†์„ฑ ์ •๋ณด์˜ ๊ตฌ์กฐ์ฒด๊ฐ€ ๋“ค์–ด๊ฐ€๋Š”๋ฐ, ์•„๋ฌด๋ž˜๋„ ๊ฐ์ฒด๋กœ๋„ ๋ณด๋Š” ๊ฒƒ ๊ฐ™๋‹ค(์†์„ฑ๊ฐ์ฒด ๋ผ๊ณ  ํ•œ๋‹ค ์นด๋”๋ผ). ์จŒ๋“  ์ธ์ž๋กœ๋Š” pthread_attr_t ๋ผ๋Š” ์ž๋ฃŒํ˜•์„ ์ด์šฉํ•œ๋‹ค. ์ด์šฉํ•  ๋•

pthread_attr_t attr;
pthread_attr_init(&attr);

์œ„ ์ฒ˜๋Ÿผ ์ด์šฉํ•˜๋ฉด ๋œ๋‹ค.

์“ฐ๋ž˜๋“œ ์†์„ฑ ์„ค์ •

๋‹ค๋ฅธ ์†์„ฑ ํ•จ์ˆ˜(scope ๊ด€๋ จ ์ปค๋„ ๋ชจ๋“œ์ธ์ง€ ๋“ฑ๋“ฑ,,,)๋„ ์žˆ๋Š”๋ฐ, ์—ฌ๊ธฐ์„œ๋Š” pthread_attr_setdetachstate ๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ์–ธ๊ธ‰ํ•  ๊ฒƒ์ด๋‹ค.

pthread_attr_setdetachstate(์†์„ฑ ์ž๋ฃŒํ˜• ํฌ์ธํ„ฐ, ์†์„ฑ์ด๋ฆ„)

์†์„ฑ์„ joinable ์ธ์ง€ detached ์ธ์ง€ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋Š” ํ•จ์ˆ˜๋‹ค. ์ด์šฉ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ดˆ๊ธฐํ™”์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

pthread_attr_t attr;์šฉ
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

PTHREAD_CREATE_JOINABLE

  • pthread_join ํ•จ์ˆ˜์™€ ๊ฐ™์ด ์ด์šฉํ•œ๋‹ค.
  • joinable ์†์„ฑ์—์„œ pthread_join ํ˜ธ์ถœ์‹œ ์“ฐ๋ž˜๋“œ๊ฐ€ ๋๋‚ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์ค€๋‹ค.

PTHREAD_CREATE_DETACHED

  • pthread_detach ํ•จ์ˆ˜์™€ ๊ฐ™์ด ์ด์šฉํ•œ๋‹ค.
  • detached ์†์„ฑ์—์„œ pthread_detach ํ˜ธ์ถœ์‹œ ์“ฐ๋ž˜๋“œ๊ฐ€ ๋๋‚ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๋Š”๋‹ค.
  • ์“ฐ๋ž˜๋“œ๋Š” ์ž๊ธฐ๊ฐ€ ๋๋‚˜๋ฉด ์•Œ์•„์„œ ์ž์›์„ ๋ชจ๋‘ ํ•ด์ œํ•œ๋‹ค.

์„ค์ •์ด ๋๋‚œ ์†์„ฑ ์ œ๊ฑฐ

์œ„์˜ ์†์„ฑ ์„ค์ •๊นŒ์ง€ ํ•œ ํ›„ pthread_create๋ฅผ ์ด์šฉํ•ด ์“ฐ๋ž˜๋“œ๋ฅผ ์ƒ์„ฑํ•˜๋ฉด, ๋”์ด์ƒ ์†์„ฑ๊ฐ์ฒด๋Š” ํ•„์š”๊ฐ€ ์—†์–ด์ง„๋‹ค.

pthread_attr_destroy(์†์„ฑ ์ž๋ฃŒํ˜• ํฌ์ธํ„ฐ)

์†์„ฑ๊ฐ์ฒด attr์ด ์žˆ๋‹ค๋ฉด, ์ด์šฉ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ•˜๋ฉด ๋œ๋‹ค.

pthread_attr_destroy(&attr);

/practice10/ex10.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>

void* work(void *null)
{
	int i;
	double result = 0.0;
	for(i = 0; i < 100000; i++)
		result +=(double)random();
	printf("result = %e\n", result);

	pthread_exit((void*)0);
}

int main(void)
{
	pthread_t thread[3];
	pthread_attr_t attr;
	int rc, t;

	void* status;

	pthread_attr_init(&attr); //์†์„ฑ๊ฐ์ฒด ์ƒ์„ฑ
	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); //joinable๋กœ ์†์„ฑ ์„ค์ •
	
	for(t = 0; t < 3; t++)
	{
		printf("Creating thread %d\n", t);
		rc = pthread_create(&thread[t], &attr, work, NULL);
	}

	pthread_attr_destroy(&attr); //์†์„ฑ์ œ๊ฑฐ
	for(t = 0; t < 3; t++)
	{
		rc = pthread_join(thread[t], &status);
		printf("Completed join with thread %d status = %ld\n", t, (long)status);
	}

	pthread_exit(NULL);

	return 0;
}
Creating thread 0
Creating thread 1
Creating thread 2
result = 1.073075e+14
Completed join with thread 0 status = 0
result = 1.075923e+14
Completed join with thread 1 status = 0
result = 1.072782e+14
Completed join with thread 2 status = 0

์‚ฌ์‹ค joinable ์€ ๊ธฐ๋ณธ ์„ค์ •์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ตณ์ด ๋ณ„๋„๋กœ ์„ค์ •ํ•  ํ•„์š”๋Š” ์—†์ง€๋งŒ, ์—ฐ์Šต์‚ผ์•„ ํ•œ๋ฒˆ ์„ค์ •์„ ํ•ด๋ดค๋‹ค.
joinable๋กœ ์“ฐ๋ž˜๋“œ ์ƒ์„ฑํ›„, ๊ฐ ์“ฐ๋ž˜๋“œ๋Š” ๋žœ๋คํ•œ ๊ฐ’์„ ์‹ญ๋งŒ๋ฒˆ ๋”ํ•œ ํ›„ ๊ฒฐ๊ณผ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.
๋ฉ”์ธ ๋ฌธ์—์„œ๋Š” ์“ฐ๋ž˜๋“œ 0๋ฒˆ ๋ถ€ํ„ฐ 2๋ฒˆ๊นŒ์ง€ ์ˆœ์„œ๋Œ€๋กœ ๋๋‚ ๊ฒƒ์„ ๊ธฐ๋Œ€ํ•˜๊ณ  pthread_join์„ ํ•œ๋‹ค.

๋ฎคํ…์Šค

์“ฐ๋ž˜๋“œ๊ฐ„์— ์„œ๋กœ ๊ณต์œ ํ•˜๋Š” ์ž์›์ด ์žˆ๋‹ค. ๊ทผ๋Œ€ ์ด ๊ณต์œ ์ž์›์— ์ž‘์—…์„ ํ•˜๊ณ  ์žˆ๋Š”๋ฐ, ๊ฐ€๋” ๋‹ค๋ฅธ ์“ฐ๋ž˜๋“œ๊ฐ€ ์น˜๊ณ  ๋“ค์–ด์™€์„œ ์ด์ƒํ•œ ์ง“์„ ํ•˜๊ณ  ๊ฐ„๋‹ค. ๊ทธ๋Ÿฐ๊ฑธ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ๋ฎคํ…์Šค๋‹ค. ๋‹ค๋ฅธ RTOS ์—์„œ๋„ ๋ฎคํ…์Šค๋‚˜ ์„ธ๋งˆํฌ์–ด๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์ง€์›ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ต์ˆ™ํ–ˆ๋‹ค.

๋ฎคํ…์Šค ์ƒ์„ฑ๊ณผ ์ดˆ๊ธฐํ™”

pthread_mutex_init(๋ฎคํ…์Šค ์ž๋ฃŒํ˜• ํฌ์ธํ„ฐ, ์†์„ฑ)

์—ฌ๊ธฐ์„œ๋„ ๋ฎคํ…์Šค๊ฐ์ฒด ๋ผ๊ณ  ํ•˜๋˜๋ฐ, c์—์„œ ๊ฐ์ฒด๋ผ๊ณ  ํ•˜๋‹ˆ ์ข€ ์ด์ƒํ•œ ๋Š๋‚Œ๋„ ๋“ ๋‹ค(๊ฐ์ฒด๋ผ๋Š”๊ฒŒ ๊ฐœ๋…์ ์ธ๊ฑฐ๋‹ˆ ๋ญ,,,). ์ž๋ฃŒํ˜•์ด pthread_mutex_t์ธ ๊ตฌ์กฐ์ฒด(๊ฐ์ฒด๋ผ๊ณ  ํ•ด์•ผํ•˜๋ƒ,,,)๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ์†์„ฑ์€ ๋‹ค๋ฅธ ์†์„ฑ์ด ์žˆ๋‹ค๋Š”๊ฒƒ ๊ฐ™์€๋ฐ, ์–ด์ฐจํ”ผ ํฌ๋ฆฌํ‹ฐ์ปฌ ์„น์…˜์„ ๋งŒ๋“œ๋Š” ๊ฒƒ์—์„œ๋งŒ ์“ฐ๊ธฐ ๋•Œ๋ฌธ์—,,, ๊ธฐ๋ณธ ๋ชจ๋“œ์ธ fast ๋ชจ๋“œ๋งŒ ์‚ฌ์šฉํ•  ๊ฒƒ ๊ฐ™๋‹ค. ๊ธฐ๋ณธ ๋ชจ๋“œ๋กœ ์‚ฌ์šฉํ• ๋ ค๋ฉด ์†์„ฑ์— NULL๊ฐ’์„ ๋„ฃ์–ด์ฃผ๋ฉด ๋œ๋‹ค.

pthread_mutex_t ๋กœ ์„ ์–ธ๋œ ๋ณ€์ˆ˜๋Š” ์ „์—ญ๋ณ€์ˆ˜๋กœ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ์“ฐ๋ž˜๋“œ ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ๋„ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์—,,,

์‚ฌ์šฉ์€

pthread_mutex_t mutex;
pthread_mutex_init(&mutex, NULL);

๊ณผ ๊ฐ™์ด ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

๋ฎคํ…์Šค ์‚ญ์ œ

pthread_mutex_destroy(๋ฎคํ…์Šค ์ž๋ฃŒํ˜• ํฌ์ธํ„ฐ)

์ž‘์—…ํ•  ์“ฐ๋ž˜๋“œ๊ฐ€ ๋ชจ๋‘ ๋๋‚˜๊ณ , ๋ฎคํ…์Šค๊ฐ€ ๋”์ด์ƒ ์“ธ๋ชจ ์—†์„๋•Œ ์ง€์šฐ๋Š” ์—ญํ• ์ด๋‹ค. ๋”ฑํžˆ ๋” ์–ธ๊ธ‰ํ• ๊ฒŒ ์—†๋Š”๊ฒƒ ๊ฐ™๋‹ค.

pthread_mutex_destroy(&mutex);

์‚ฌ์šฉ๋ฒ•๋„ ๋ญ,,,

ํฌ๋ฆฌํ‹ฐ์ปฌ ์„น์…˜ ๋งŒ๋“ค๊ธฐ

pthread_mutex_lock(๋ฎคํ…์Šค ์ž๋ฃŒํ˜• ํฌ์ธํ„ฐ)
pthread_mutex_unlock(๋ฎคํ…์Šค ์ž๋ฃŒํ˜• ํฌ์ธํ„ฐ)

๋ฎคํ…์Šค๋กœ ํฌ๋ฆฌํ‹ฐ์ปฌ ์„น์…˜ ๋งŒ๋“œ๋Š”๊ฑด ํฌ๊ฒŒ ์–ด๋ ต์ง€ ์•Š๋‹ค. ๋ฎคํ…์Šค๊ฐ€ ๋ญ”์ง€๋งŒ ์•Œ์•„๋„ ์ดํ•ด๊ฐ€ ๋  ๊ฒƒ์ด๋‹ค. ์–ด๋–ค ๊ฐ’์ด ์žˆ๋Š”๋ฐ, ์ƒํƒœ๊ฐ€ '์‚ฌ์šฉ์ค‘'๊ณผ '์‚ฌ์šฉ์•ˆํ•จ'์ด ์žˆ๋‹ค. ๋งŒ์•ฝ ์‚ฌ์šฉ์•ˆํ•จ ์ƒํƒœ๋ผ๋ฉด ์‚ฌ์šฉ์„ ์œ„ํ•ด lock์„ ๊ฑธ์–ด ์‚ฌ์šฉ์ค‘์œผ๋กœ ๋ฐ”๊พผ๋‹ค. ์‚ฌ์šฉ์ด ๋๋‚˜๋ฉด unlock ํ•ด์„œ ์‚ฌ์šฉ์•ˆํ•จ์œผ๋กœ ๋ฐ”๊ฟ”์ค€๋‹ค.

๋งŒ์•ฝ val ์ด๋ž€ ๋ณ€์ˆ˜๋ฅผ ์“ฐ๋ž˜๋“œ๊ฐ„์— ๊ณต์œ ํ•˜๊ณ , ํฌ๋ฆฌํ‹ฐ์ปฌ ์„น์…˜์„ ๋งŒ๋“ค์–ด ๋ณ€๊ฒฝํ•ด์•ผ ํ•œ๋‹ค๋ฉด

pthread_mutex_lock(&mutex);
val++;
pthread_mutex_unlock(&mutex);

์ด์™€ ๊ฐ™์ด lock๊ณผ unlock ์‚ฌ์ด์— ๋ณ€๊ฒฝํ•  ๊ฒƒ๋“ค์„ ๋ผ์›Œ ๋„ฃ์œผ๋ฉด ๊ทธ๋งŒ.

/practice11/ex11.c

#define NITERS 100000000
#include <stdio.h>
#include <pthread.h>


unsigned int cnt = 0;
void* count(void *data);
pthread_mutex_t mutex; //๋ฎคํ…์Šค ๊ฐ์ฒด ์ƒ์„ฑ


int main(void)
{
	pthread_t tid1, tid2;
	pthread_mutex_init(&mutex, NULL); //๋ฎคํ…์Šค ์„ค์ • ์ดˆ๊ธฐํ™”
	pthread_create(&tid1, NULL, count, NULL);
	pthread_create(&tid2, NULL, count, NULL);
	pthread_join(tid1, NULL);
	pthread_join(tid2, NULL);
	pthread_mutex_destroy(&mutex); //๋ฎคํ…์Šค ์„ค์ • ์‚ญ์ œ

	if(cnt != (unsigned)NITERS*2)
	{
		printf("BOOM! cnt = %d\n", cnt);
	}
	else
	{
		printf("OK! cnt = %d\n", cnt);
	}

	return 0;
}

void* count(void* data)
{
	int i;
	for(i = 0; i < NITERS; i++)
	{
		pthread_mutex_lock(&mutex);
		cnt++;
		pthread_mutex_unlock(&mutex);
	}
}

์“ฐ๋ž˜๋“œ ๋‘๊ฐœ๋ฅผ ๋งŒ๋“ค์–ด cnt๋ผ๋Š” ์ „์—ญ๋ณ€์ˆ˜์— ๊ฐ๊ฐ NITERS(100000)๋งŒํผ ๋”ํ•˜๋Š” ๊ฐ„๋‹จํ•œ ์˜ˆ์ œ๋‹ค. ์“ฐ๋ž˜๋“œ ๋‘๊ฐœ๊ฐ€ ๊ฐ๊ฐ ๋”ํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ ๊ฒฐ๊ณผ๋Š” NITERS์˜ ๋‘๋ฐฐ์— ํ•ด๋‹นํ•˜๋Š” ๊ฐ’์ด ๋‚˜์™€์•ผ ํ•œ๋‹ค. ๋ฎคํ…์Šค๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ์ƒํ˜ธ๋ฐฐ์ œ๊ฐ€ ์•ˆ๋˜์–ด ์ˆœ์„œ๊ฐ€ ๊ผฌ์—ฌ ์ œ๋Œ€๋กœ ๋‘๋ฐฐ๊ฐ€ ์•ˆ๋œ๋‹ค.

๋ฎคํ…์Šค๋ฅผ ์‚ฌ์šฉ ์•ˆํ–ˆ์„๋•Œ, ๊ณ„์‚ฐ์€ ๋นจ๋ฆฌ ๋๋‚ฌ์ง€๋งŒ ์ž๊พธ ์ด์ƒํ•œ ๊ฒฐ๊ณผ๊ฐ’์ด ๋‚˜์™”๋‹ค. ์–ด์…ˆ๋ธ”๋ฆฌ์–ด ๋ ˆ๋ฒจ๋กœ ๋“ค์–ด๊ฐ€์„œ ํ™•์ธํ•ด๋ณด๋ฉด ์™œ ๊ทธ๋Ÿฐ์ง€ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ๊ทธ๋ƒฅ ์„ค๋ช…ํ•ด๋ณด๊ธฐ๋กœ ํ•˜์ž. cnt++์— ํ•ด๋‹นํ•˜๋Š” ๋‚ด์šฉ์ด ๋Œ€์ถฉ ์•„๋ž˜๊ฐ™์€ ์ˆœ์„œ๋ฅผ ๊ฐ€์งˆ ๊ฒƒ์ด๋‹ค.

  • cnt์˜ ๊ฐ’์„ ๋ ˆ์ง€์Šคํ„ฐ์— ๋ณต์‚ฌ
  • ๋ ˆ์ง€์Šคํ„ฐ์—์„œ ๊ฐ’์„ 1๋”ํ•จ
  • ๊ทธ ๊ฐ’์„ ๋‹ค์‹œ cnt์— ๋ณต์‚ฌ

๋ญ ์ด๋Ÿฐ ์ˆœ์„œ๋‹ค. ์–ด์…ˆ๋ธ”๋ฆฌ์–ด๋ฅผ ๋‚˜์—ดํ•˜๋ผ๊ณ  ํ•˜๋ฉด ์Œ,,, (๊ตฐ์ƒํ™œ๋กœ ๋น ๊ฐ€๋œ ๋จธ๋ฆฌ๋กœ ๊ณผ์—ฐ ์–ด์…ˆ๋ธ”๋ฆฌ์–ด๋ฅผ ๋ณด๊ณ  ๋•Œ๋ ค์น˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์„๊นŒ?)
์จ‹๋“  ๋ณต์‚ฌํ•˜๊ณ  ๋ณต์‚ฌํ•˜๋Š” ๊ณผ์ •์—์„œ ๋‹ค๋ฅธ ์“ฐ๋ž˜๋“œ๊ฐ€ ์น˜๊ณ  ๋“ค์–ด์™€์„œ ๋ณ€๊ฒฝํ•ด๋ฒ„๋ฆฌ๋ฉด ๋‹น์—ฐํžˆ ์ด์ƒํ•œ ๊ฐ’์ด ๋˜๋ฒ„๋ฆด๊ฑฐ๋‹ค. ๊ทธ๋ž˜์„œ ๋ฎคํ…์Šค๊ฐ€ ํ•„์š”ํ•˜๋‹ค.
(์—์ดˆ์— ์ „์—ญ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๊ฒŒ ๋งˆ์Œ์— ์•ˆ๋“ค๊ธด ํ•˜์ง€๋งŒ ใ…กใ…ก;)

์ € ์†Œ์Šค๋Œ€๋กœ ๋ฎคํ…์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์†๋„๋Š” ์ข€ ํฌ๊ฒŒ ๋–จ์–ด์ง€๊ธด ํ•ด๋„ ์ •์ƒ์ ์ธ ์ถœ๋ ฅ์€ ๋‚˜์˜จ๋‹ค. for๋ฌธ ๋ฐ–์— ๋‘๋ฉด ์ข€ ๋” ๋นจ๋ฆฌ์ง€๊ธด ํ•˜๊ฒ ์ง€.

โš ๏ธ **GitHub.com Fallback** โš ๏ธ