# Mutex

<figure><img src="/files/T1pNGNZMSpzCg4dB3Q7u" alt=""><figcaption><p>Mutex lock</p></figcaption></figure>

## Mutex คืออะไร

Mutex ย่อมาจาก "Mutual Exclusion" เป็นพื้นฐานการซิงโครไนซ์ที่ใช้เพื่อให้แน่ใจว่ามีเพียงหนึ่งเธรดในแต่ละครั้งเท่านั้นที่สามารถเข้าถึงทรัพยากรที่ใช้ร่วมกันได้

การใช้งานทั่วไปสำหรับ mutexes คือการปกป้องส่วนที่สำคัญของโค้ด ซึ่งเป็นส่วนของโค้ดที่เข้าถึงโครงสร้างข้อมูลที่ใช้ร่วมกันหรือทรัพยากรอื่นๆ ตัวอย่างเช่น เราอาจใช้ mutex เพื่อป้องกันการเข้าถึงตัวแปรที่ใช้ร่วมกันในโปรแกรมแบบมัลติเธรด โดยใช้ล็อก mutex ก่อนเข้าถึงตัวแปรที่ใช้ร่วมกัน และปลดล็อกหลังจากดำเนินการเสร็จสิ้น เราจะมั่นใจได้ว่ามีเธรดเดียวเท่านั้นที่เข้าถึงตัวแปรได้ในแต่ละครั้ง

### **ตัวอย่างที่ 1**

ป้องกันการเข้าถึงตัวแปรที่ใช้ร่วมกันในโปรแกรม

{% code title="Mutex.cpp" %}

```
#include <iostream>
#include <thread>
#include <mutex>
using namespace std;

int myAmount = 0;
std::mutex Mutex;

void addMoney(){ 
    Mutex.lock();
    ++myAmount;
    Mutex.unlock();
}

int main(){

    std::thread t1(addMoney);
    std::thread t2(addMoney);
    t1.join();
    t2.join();
    cout << myAmount << endl;
    return 0;

}
// Note: for compile Thread you need to add -pthread to the command line too.
// eg.  g++ -pthread Mutex.cpp -o Output.exe
```

{% endcode %}

**Output**

```
2
```

### **ตัวอย่างที่ 2**

{% code title="Mutex.cpp" %}

```cpp
// mutex example
#include <iostream>       // std::cout
#include <thread>         // std::thread
#include <mutex>          // std::mutex

std::mutex mtx;           // mutex for critical section
void print_block (int n, char c) {
  // critical section (exclusive access to std::cout signaled by locking mtx):
  mtx.lock();
  for (int i=0; i<n; ++i) { std::cout << c; }
  std::cout << '\n';
  mtx.unlock();
}

int main ()
{
  std::thread th1 (print_block,500,'*');
  std::thread th2 (print_block,500,'$');
  th1.join();
  th2.join();
  return 0;
}
```

{% endcode %}

```
********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
```

### **ตัวอย่างที่ 3**

ตัวอย่างของเธรด 3 ตัวที่พยายามเข้าไปใช้ list เดียวกัน myList:

{% tabs %}
{% tab title="Without Mutex" %}
{% code title="3\_threads.cpp" %}

```cpp
#include <iostream>
#include <thread>
#include <list>
#include <algorithm>

using namespace std;

// a global variable
std::list<int> myList;

void addToList(int max, int interval)
{
	for (int i = 0; i < max; i++) {
		if( (i % interval) == 0) myList.push_back(i);
	}
}

void printList()
{
	for (auto itr = myList.begin(), end_itr = myList.end(); itr != end_itr; ++itr ) {
		cout << *itr << ",";
	}
}

int main()
{
	int max = 100;

	std::thread t1(addToList, max, 1);
	std::thread t2(addToList, max, 10);
	std::thread t3(printList);

	t1.join();
	t2.join();
	t3.join();

    cout << endl;

	return 0;
}
```

{% endcode %}
{% endtab %}

{% tab title="With Mutex" %}
{% code title="With\_Mutex.cpp" %}

```cpp
#include <iostream>
#include <thread>
#include <list>
#include <algorithm>
#include <mutex>

using namespace std;

// a global variable
std::list<int>myList;

// a global instance of std::mutex to protect global variable
std::mutex myMutex;

void addToList(int max, int interval)
{
	// the access to this function is mutually exclusive
	std::lock_guard<std::mutex> guard(myMutex);
	for (int i = 0; i < max; i++) {
		if( (i % interval) == 0) myList.push_back(i);
	}
}

void printList()
{
	// the access to this function is mutually exclusive
	std::lock_guard<std::mutex> guard(myMutex);
	for (auto itr = myList.begin(), end_itr = myList.end(); itr != end_itr; ++itr ) {
		cout << *itr << ",";
	}
}

int main()
{
	int max = 100;

	std::thread t1(addToList, max, 1);
	std::thread t2(addToList, max, 10);
	std::thread t3(printList);

	t1.join();
	t2.join();
	t3.join();

    cout << endl;

	return 0;
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

*Output*

{% tabs %}
{% tab title="Output without Mutex" %}
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,<mark style="color:red;">0</mark>,91,<mark style="color:red;">10,20</mark>,94,<mark style="color:red;">30</mark>,96,<mark style="color:red;">40</mark>,97,<mark style="color:red;">50</mark>,98,<mark style="color:red;">60</mark>,99,<mark style="color:red;">70,80,90,</mark>
{% endtab %}

{% tab title="Output with Mutex" %}
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,<mark style="color:red;">0,10,20,30,40,50,60,70,80,90,</mark>
{% endtab %}
{% endtabs %}

Ref:

* <https://medium.com/swlh/c-mutex-write-your-first-concurrent-code-69ac8b332288>
* <https://www.bogotobogo.com/cplusplus/multithreaded4_cplusplus11B.php>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.aic-eec.com/c-c++-for-embedded-programming/high-performance-programing/mutex.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
