> For the complete documentation index, see [llms.txt](https://docs.aic-eec.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.aic-eec.com/c-c++-for-embedded-programming/high-performance-programing/mutex.md).

# Mutex

<figure><img src="https://1856353139-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MClo3nC-1US0rbK8Qau%2Fuploads%2FLkJ5KM1tN5BLOTwceojp%2Fimage.png?alt=media&amp;token=3d66f35f-6141-45ae-aeda-ed548b498ebe" 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>
