线程互斥与同步 在c#中用mutex类实现线程的互斥_Linux内核同步,进程,线程同步...

前言:

本文浅谈两个知识点:

1:用户级线程和内核级线程的区别,以及各个优缺点

2:linux内核同步,进程,线程同步

f11efcc6a7934e158a10f2742b468460.png

一:用户级线程和内核级线程的区别

(1)内核支持线程是OS内核可感知的,而用户级线程是OS内核不可感知的。

(2)用户级线程的创建、撤消和调度不需要OS内核的支持,是在语言(如Java)这一级处理的;而内核支持线程的创建、撤消和调度都需OS内核提供支持,而且与进程的创建、撤消和调度大体是相同的。

(3)用户级线程执行系统调用指令时将导致其所属进程被中断,而内核支持线程执行系统调用指令时,只导致该线程被中断。

(4)在只有用户级线程的系统内,CPU调度还是以进程为单位,处于运行状态的进程中的多个线程,由用户程序控制线程的轮换运行;在有内核支持线程的系统内,CPU调度则以线程为单位,由OS的线程调度程序负责线程的调度。

(5)用户级线程的程序实体是运行在用户态下的程序,而内核支持线程的程序实体则是可以运行在任何状态下的程序。

内核线程的优点:

(1)当有多个处理机时,一个进程的多个线程可以同时执行。

缺点:

(1)由内核进行调度。

用户进程的优点:

(1) 线程的调度不需要内核直接参与,控制简单。

(2) 可以在不支持线程的操作系统中实现。

(3) 创建和销毁线程、线程切换代价等线程管理的代价比内核线程少得多。

(4) 允许每个进程定制自己的调度算法,线程管理比较灵活。

(5) 线程能够利用的表空间和堆栈空间比内核级线程多。

(6) 同一进程中只能同时有一个线程在运行,如果有一个线程使用了系统调用而阻塞,那么整个进程都会被挂起。另外,页面失效也会产生同样的问题。

缺点:

(1)资源调度按照进程进行,多个处理机下,同一个进程中的线程只能在同一个处理机下分时复用

二:内核同步

主要是防止多核处理器同时访问修改某段代码,或者在对设备驱动程序进行临界区保护。主要有一下几种方式:

1. Mutex(互斥)

头文件:

#include

初始化方法:

DEFINE_MUTEX(name);

或者

void mutex_init(struct mutex *lock);

使用方法:

void mutex_lock (struct mutex *lock);

尝试得到互斥量,否则进入睡眠,不能被中断,否则会导致进程无法杀死


int mutex_lock_interruptible (struct mutex *lock);
Same, but can be interrupted. If interrupted, returns a non zero value and doesn't hold the lock. Test the return value!!!

可以被中断


int mutex_trylock (struct mutex *lock);
Never waits. Returns a non zero value if the mutex is not http://available.intmutex_is_locked(struct mutex *lock);Just tells whether the mutex is locked or not.

无等待


void mutex_unlock (struct mutex *lock);
Releases the lock. Make sure you do it as quickly as possible!

2. Reader/writer semphopres 读写信号量

Allow shared access by unlimited readers, or by only 1 writer. Writers get priority.

允许有限数量的读访问,但是只能有一个写访问。
void init_rwsem (struct rw_semaphore *sem);
void down_read (struct rw_semaphore *sem);
int down_read_trylock (struct rw_semaphore *sem);
int up_read (struct rw_semaphore *sem);
void down_write (struct rw_semaphore *sem);
int down_write_trylock (struct rw_semaphore *sem);
int up_write (struct rw_semaphore *sem);
Well suited for rare writes, holding the semaphore briefly. Otherwise, readers get starved, waiting too long for the semaphore to be released.

3. Spinlocks 自旋锁

初始化:

Static
spinlock_t my_lock = SPIN_LOCK_UNLOCKED;
Dynamic
void spin_lock_init (spinlock_t *lock);

使用:

void spin_[un]lock (spinlock_t *lock);
Doesn't disable interrupts. Used for locking in process context (critical sections in which you do not want to sleep).
void spin_lock_irqsave / spin_unlock_irqrestore (spinlock_t *lock, unsigned long flags);
Disables / restores IRQs on the local CPU.
Typically used when the lock can be accessed in both process and interrupt context, to prevent preemption by interrupts

三:进程同步/通信

1. Semaphore 信号量

简单过程:

semaphore sv = 1;
loop forever {
P(sv);
critical code section;
V(sv);
noncritical code section;
}

头文件以及函数:

#include
int semctl(int sem_id, int sem_num, int command, ...);
int semget(key_t key, int num_sems, int sem_flags);
int semop(int sem_id, struct sembuf *sem_ops, size_t num_sem_ops);

2.Share Memory 共享内存

头文件以及函数

#include
void *shmat(int shm_id, const void *shm_addr, int shmflg);
int shmctl(int shm_id, int cmd, struct shmid_ds *buf);
int shmdt(const void *shm_addr);
int shmget(key_t key, size_t size, int shmflg);

3.Message Queues 消息队列

头文件以及函数

#include
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
int msgget(key_t key, int msgflg);
int msgrcv(int msqid, void *msg_ptr, size_t msg_sz, long int msgtype, int msgflg);
int msgsnd(int msqid, const void *msg_ptr, size_t msg_sz, int msgflg);

四:线程同步

1. semophore 信号量

简单用法:

#include

sem_t bin_sem;

res = sem_init(&bin_sem, 0, 0);

sem_wait(&bin_sem);

sem_post(&bin_sem);

sem_destroy(&bin_sem);

2. Mutex 互斥

头文件以及函数

#include
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);
int pthread_mutex_lock(pthread_mutex_t *mutex));
int pthread_mutex_unlock(pthread_mutex_t *mutex);
int pthread_mutex_destroy(pthread_mutex_t *mutex);


3. 读写锁

头文件以及函数

#include
int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr);
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);
4. 条件变量
#include
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr);
int pthread_cond_signal(pthread_cond_t *cond);
int pthread_cond_broadcast(pthread_cond_t *cond);
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime);
int pthread_cond_destroy(pthread_cond_t *cond);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值