Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to analyze mutex.c based on Linux thread 2.0.1 thread source code

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.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report