POSIX 线程中的互斥量概念

发布于 2024-11-15 16:24:07 字数 239 浏览 2 评论 0原文

谁能告诉我如何在 posix 线程中使用互斥体。 我们将互斥体声明为 pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER.. 我们使用 pthread_mutex_lock(&mutex1) 来锁定关键代码。 但我的问题是它锁什么 我们没有指定要锁定哪个代码 如果我有 4 个线程并且我希望线程 1 资源被锁定,我如何告诉编译器 我无法理解,任何人都可以帮助我。 互斥体的真正用途是什么 等待答案..

could anyone tell me how to use the mutex in the posix threads.
we are decalaring a mutex as pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER..
and we are using pthread_mutex_lock(&mutex1) to lock the critical code.
but my question is what does it lock
we didnt specify which code to be locked
if i have 4 threads and i want the thread 1 resources to be locked how could i tell that to the compiler
and im unable to understand it can anyone help me guys.
and whats the real use of mutex
waiting for an answer ..

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

草莓酥 2024-11-22 16:24:07

这完全由您决定,pthreads 不指定锁保护或不保护什么。

例如,如果您想保护变量“a”,则需要确保对“a”的所有访问都在互斥锁(例如“a_lock”)的保护下进行。对于一个简单的(未经测试的)示例


static int a;
static pthread_mutex_t a_lock = PTHREAD_MUTEX_INITIALIZER;

/* Add argument to static variable a in a thread-safe manner and return the result.  (In real life, for this kind of operation you could use an atomic operation) */
int increment_a(int i)
{
  int res;
  pthread_mutex_lock(&a_lock);
  a += i;
  res = a;
  pthread_mutex_unlock(&a_lock);
  return res;
}

也就是说,硬件、操作系统、线程库或其他任何东西都没有指定您想要保护的数据之间的任何类型的关系(上例中的变量“a”),以及用于实现所述保护的互斥锁(上面的互斥锁“a_lock”)。 pthread 库仅确保一次只有一个线程可以持有互斥体。

It's entirely up to you to decide, pthreads doesn't specify what a lock does or does not protect.

E.g. if you want to protect a variable "a", it's up to you to ensure that all accesses to "a" happen under the protection of a mutex (say, "a_lock"). For a simple (untested) example


static int a;
static pthread_mutex_t a_lock = PTHREAD_MUTEX_INITIALIZER;

/* Add argument to static variable a in a thread-safe manner and return the result.  (In real life, for this kind of operation you could use an atomic operation) */
int increment_a(int i)
{
  int res;
  pthread_mutex_lock(&a_lock);
  a += i;
  res = a;
  pthread_mutex_unlock(&a_lock);
  return res;
}

That is, there is nothing in the hardware, OS, thread library, or anything else, that specifies any kind of relationship between the data you want to protect (variable "a" in the example above), and the mutex you're using to implement said protection (the mutex "a_lock" above). The pthread library only ensures that only one thread at a time may hold a mutex.

红墙和绿瓦 2024-11-22 16:24:07

它锁定、保护的代码,它是锁定和解锁之间的代码

pthread_mutex_lock(&mtx)
global_var = global_var + 10;
pthread_mutex_unlock(&mtx)

在这个简单的情况下,您正在保护此全局变量的增量,这是必要的,因为递增数字的过程需要三个步骤:

  1. 从 ram 读取当前值
  2. 增加该值将该
  3. 值写回 ram

让我们重点关注步骤 1 和 2。在步骤 1(读取)之后,线程可以(并且肯定会)进行切换,而另一个线程将读取该值相同的value 作为第一个,因为它从未有机会更新回 ram。当第一个线程恢复工作时(就在步骤 1 之后),它将递增之前读取的值,并将错误的最终值写回 ram,从而覆盖第二个线程的工作。

换句话说:

[Thread 1] Reads the value 10
[Thread 2] Reads the value 10
[Thread 2] Increments it by 5 (value is now 15)
[Thread 2] Writes it back
[Thread 1] Increments it by 5 **(value is now 15)**
[Thread 1] Writes it back
Final value: 15

最终值应该是 20,而不是 15。看到问题了吗?
使用互斥体,您可以序列化访问,将内容按正确的顺序排列,因此

[Thread 1] Reads the value 10
[Thread 1] Increments it by 5 (value is now 15)
[Thread 1] Writes it back
[Thread 2] Reads the value 15
[Thread 2] Increments it by 5 (value is now 20)
[Thread 2] Writes it back
Final value: 20

如果我感到困惑,我很抱歉,但线程编程一开始很令人困惑。需要一段时间来思考多线程,但请留在那里!这是一个需要掌握的非常重要的概念,尤其是现在多核 CPU 已成为事实上的标准。

The code it locks, protects, its the code between the lock and the unlock

pthread_mutex_lock(&mtx)
global_var = global_var + 10;
pthread_mutex_unlock(&mtx)

In this simple case you are protecting the increments of this global variable, this is necessary because the process of incrementing a number takes three steps:

  1. Reading the current value from ram
  2. Incrementing that value
  3. Writing that value back into ram

Let's focus on steps 1 and 2. A thread CAN (and will be, be sure of that) be switched just after step 1 (reading), and the other thread will read the same value as the first one, because it never got the opportunity to update back to ram. When the first thread resumes work (just after step 1), it will increment that value it read before and write back the wrong final value to ram, overwriting the second's thread work.

In other words:

[Thread 1] Reads the value 10
[Thread 2] Reads the value 10
[Thread 2] Increments it by 5 (value is now 15)
[Thread 2] Writes it back
[Thread 1] Increments it by 5 **(value is now 15)**
[Thread 1] Writes it back
Final value: 15

The final value should have been 20, not 15. See the problem?
With a mutex you can serialize the access, putting stuff into proper order, so it becomes

[Thread 1] Reads the value 10
[Thread 1] Increments it by 5 (value is now 15)
[Thread 1] Writes it back
[Thread 2] Reads the value 15
[Thread 2] Increments it by 5 (value is now 20)
[Thread 2] Writes it back
Final value: 20

I'm sorry if I was confusing, but thread programming is confusing at first. Takes a while to think multithreaded, but linger there! It is a very important concept to grasp, especially now that multi-core CPUs are the de facto standard.

路还长,别太狂 2024-11-22 16:24:07

线程共享内存(堆栈和可能的线程本地存储除外)。因此,您需要采取一些措施来避免两个线程相互冲突。

互斥体是防止线程相互干扰的一种方法。互斥体是一种互斥原语,一次只有一个线程可以保存给定的互斥体。

因此,如果您想保护某些数据结构免遭多个线程同时访问,则可以将互斥体与该线程相关联,并将对该数据结构的每次访问包装到互斥体锁定和解锁调用中。这样,您可以确保一次只有一个线程可以访问该数据结构。

如果一个线程持有互斥锁,而第二个线程尝试锁定该互斥锁,则第二个线程将阻塞(睡眠),直到第一个线程解锁该互斥锁。

Threads share memory (except the stack and possibly thread-local storage). So, you need to do something to avoid two threads stomping into each other.

Mutexes are a way to prevent threads from interfering into each other. A mutex is a MUTual EXClusion primitive, only one thread can hold a given mutex at a time.

So, if you want to protect some data structure from simultaneous access from several threads, you associate a mutex with that thread, and wrap every access to that data structure into mutex lock and unlock calls. This way, you ensure that only one thread can access the data structure at a time.

If a thread holds a mutex, and a second thread tries to lock the mutex, the second thread will block (sleep) until the first thread unlocks the mutex.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文