In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-08 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/01 Report--
This article shows you how to carry out mutex.c based on Linux thread 2.0.1 thread source code analysis, the content is concise and easy to understand, it will definitely brighten your eyes. I hope you can get something through the detailed introduction of this article.
Mutex is mutually exclusive, which is used to control synchronization between multiple threads and mutually exclusive access to resources.
Related structures.
/ * Mutexes (not abstract because of PTHREAD_MUTEX_INITIALIZER). , /
Typedef struct
{
/ / spin lock
Int masked spinlock; / * Spin lock to guarantee mutual exclusion. , /
/ / for recursive locking, that is, a thread acquires the mutex multiple times. M_count recorded the number of times.
Int int count; / * 0 if free, > 0 if taken. , /
/ / record who gets the mutex and use this field when recursively locking.
Pthread_t for recursive mutexes owner; / * Owner of mutex (owner) * /
/ / the type of mutually exclusive variable, recursive or non-recursive
Int masking kinds; / * Kind of mutex * /
/ / Thread queue waiting for this mutex
Struct _ pthread_queue masking waiting; / * Threads waiting on this mutex. , /
} pthread_mutex_t
/ / initialize mutually exclusive variables with recursive or non-recursive types
# define PTHREAD_MUTEX_INITIALIZER\
{0, 0, 0, PTHREAD_MUTEX_FAST_NP, {0, 0}}
# define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP\
{0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP, {0, 0}}
Here is the code for the implementation.
/ * Linuxthreads-a simple clone ()-based implementation of Posix * /
/ * threads for Linux. , /
/ * Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) * /
/ * /
/ * This program is free software; you can redistribute it and/or * /
/ * modify it under the terms of the GNU Library General Public License * /
/ * as published by the Free Software Foundation; either version 2 * /
/ * of the License, or (at your option) any later version. , /
/ * /
/ * This program is distributed in the hope that it will be useful, * /
/ * but WITHOUT ANY WARRANTY; without even the implied warranty of * /
/ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * /
/ * GNU Library General Public License for more details. , /
/ * Mutexes * /
# include
# include
# include
# include "pthread.h"
# include "internals.h"
# include "spinlock.h"
# include "queue.h"
# include "restart.h"
/ / initialize mutex nodes with attribute structures
Int _ _ pthread_mutex_init (pthread_mutex_t * mutex
Const pthread_mutexattr_t * mutex_attr)
{
Mutex- > m_spinlock = 0
Mutex- > m_count = 0
Mutex- > m_owner = NULL
Mutex- > m_kind =
Mutex_attr = = NULL? PTHREAD_MUTEX_FAST_NP: mutex_attr- > mutexkind
Queue_init (& mutex- > m_waiting)
Return 0
}
Weak_alias (_ _ pthread_mutex_init, pthread_mutex_init)
/ / destroy the mutex
Int _ _ pthread_mutex_destroy (pthread_mutex_t * mutex)
{
Int count
Acquire (& mutex- > m_spinlock)
Count = mutex- > m_count
Release (& mutex- > m_spinlock)
/ / is in use
If (count > 0) return EBUSY
Return 0
}
Weak_alias (_ _ pthread_mutex_destroy, pthread_mutex_destroy)
/ / non-blocking acquisition lock
Int _ _ pthread_mutex_trylock (pthread_mutex_t * mutex)
{
Pthread_t self
Acquire (& mutex- > m_spinlock)
Switch (mutex- > m_kind) {
Case PTHREAD_MUTEX_FAST_NP:
/ / if it has not been used yet, the number plus one is used to return success
If (mutex- > m_count = = 0) {
Mutex- > m_count = 1
Release (& mutex- > m_spinlock)
Return 0
}
Break
/ / Recursively get mutually exclusive variables
Case PTHREAD_MUTEX_RECURSIVE_NP:
Self = thread_self ()
/ / equal to 0 means that it has not been obtained, can be obtained directly, or has been obtained by the current thread, then the number of times is increased by one.
If (mutex- > m_count = = 0 | | mutex- > m_owner = = self) {
Mutex- > massively countdown +
Mutex- > m_owner = self
Release (& mutex- > m_spinlock)
Return 0
}
Break
Default:
Return EINVAL
}
Release (& mutex- > m_spinlock)
Return EBUSY
}
Weak_alias (_ _ pthread_mutex_trylock, pthread_mutex_trylock)
/ / blocking access to mutually exclusive variables
Int _ _ pthread_mutex_lock (pthread_mutex_t * mutex)
{
Pthread_t self
While (1) {
Acquire (& mutex- > m_spinlock)
Switch (mutex- > m_kind) {
Case PTHREAD_MUTEX_FAST_NP:
If (mutex- > m_count = = 0) {
Mutex- > m_count = 1
Release (& mutex- > m_spinlock)
Return 0
}
Self = thread_self ()
Break
Case PTHREAD_MUTEX_RECURSIVE_NP:
Self = thread_self ()
/ / is equal to 0 or the thread has already acquired the mutex, then it can be obtained repeatedly, m_count accumulation
If (mutex- > m_count = = 0 | | mutex- > m_owner = = self) {
Mutex- > massively countdown +
/ / Mark that the mutex has been acquired by this thread
Mutex- > m_owner = self
Release (& mutex- > m_spinlock)
Return 0
}
Break
Default:
Return EINVAL
}
/ * Suspend ourselves, then try again * /
/ / failed to get, need to block, insert the current thread into the waiting queue of the mutex
Enqueue (& mutex- > m_waiting, self)
Release (& mutex- > m_spinlock)
/ / suspend and wait for wake-up
Suspend (self); / * This is not a cancellation point * /
}
}
Weak_alias (_ _ pthread_mutex_lock, pthread_mutex_lock)
Int _ _ pthread_mutex_unlock (pthread_mutex_t * mutex)
{
Pthread_t th
Acquire (& mutex- > m_spinlock)
Switch (mutex- > m_kind) {
Case PTHREAD_MUTEX_FAST_NP:
Mutex- > m_count = 0
Break
Case PTHREAD_MUTEX_RECURSIVE_NP:
Mutex- > musecountMutual-
If (mutex- > m_count > 0) {
Release (& mutex- > m_spinlock)
Return 0
}
Mutex- > m_count = 0; / * so that excess unlocks do not break everything * /
Break
Default:
Return EINVAL
}
/ / take out a blocked thread (if any) and wake him up
Th = dequeue (& mutex- > m_waiting)
Release (& mutex- > m_spinlock)
If (th! = NULL) restart (th)
Return 0
}
Weak_alias (_ _ pthread_mutex_unlock, pthread_mutex_unlock)
Int _ _ pthread_mutexattr_init (pthread_mutexattr_t * attr)
{
Attr- > mutexkind = PTHREAD_MUTEX_FAST_NP
Return 0
}
Weak_alias (_ _ pthread_mutexattr_init, pthread_mutexattr_init)
Int _ _ pthread_mutexattr_destroy (pthread_mutexattr_t * attr)
{
Return 0
}
Weak_alias (_ _ pthread_mutexattr_destroy, pthread_mutexattr_destroy)
Int _ _ pthread_mutexattr_setkind_np (pthread_mutexattr_t * attr, int kind)
{
If (kind! = PTHREAD_MUTEX_FAST_NP & & kind! = PTHREAD_MUTEX_RECURSIVE_NP)
Return EINVAL
Attr- > mutexkind = kind
Return 0
}
Weak_alias (_ _ pthread_mutexattr_setkind_np, pthread_mutexattr_setkind_np)
Int _ _ pthread_mutexattr_getkind_np (const pthread_mutexattr_t * attr, int * kind)
{
* kind = attr- > mutexkind
Return 0
}
Weak_alias (_ _ pthread_mutexattr_getkind_np, pthread_mutexattr_getkind_np)
/ / Save init_routine only once
Int pthread_once (pthread_once_t * once_control, void (* init_routine) (void))
{
If (testandset (once_control) = = 0) init_routine ()
Return 0
}
The above is how to analyze mutex.c based on Linux thread 2.0.1 thread source code. Have you learned any knowledge or skills? If you want to learn more skills or enrich your knowledge reserve, you are welcome to follow the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.