25多线程之互斥锁

例子:利用两个子进程从50进行降序输出

int g_num=50;

//偶数

void *threadEven(void *lParam)

{

while(g_num>0)

{

if(!(g_num&1))

{

printf("even:%d\n",g_num);

}

g_num--;

usleep(1);

}

return NULL;

}

//奇数

void *threadOdd(void *lParam)

{

while(g_num>0)

{

if(g_num&1)

{

printf("odd:%d\n",g_num);

}

g_num--;

usleep(1);

}

return NULL;

}

void testMutex()

{

pthread_t thread1,thread2;

int nRet1=pthread_create(&thread1,NULL,threadOdd,NULL);

int nRet2=pthread_create(&thread2,NULL,threadEven,NULL);

printf("thread1 id:%d\t thread2 id:%d\n",(int)thread1,(int)thread2);

if(nRet1||nRet2)

{

fprintf(stderr,"fail to create thread!");

return ;

}

pthread_join(thread1,NULL);

pthread_join(thread2,NULL);

}

int main(int argc,char**argv)

{

testMutex();

return 0;

}

上面的代码表示,创建两个子进程,子进程threadOdd输出奇数,子进程threadEven输出偶数。并且奇偶数是交替输出。即从50降序输出。

如果实现奇偶数分开输出,如:先把50内的奇数或偶数输出。此时就要加锁。

线程互斥

多线程共享进程资源,访问共享资源时候,需要进行互斥操作确保数据的有效性

什么是锁操作:

比如:两人进屋子拿东西,A先进去反锁屋子,那么B就进不去。只有等A开锁出来后,才轮到B进去。

锁类型设置/获取

int pthread_mutexattr_settype(pthread_mutexattr_t*  attr, int type);

int pthread_mutexattr_gettype(pthread_mutexattr_t*  attr, int *type);

type参数:

mutex 锁类型  PTHREAD_MUTEX_XXX

NORMAL:           普通锁,不提供死锁检测,可能出现死锁

ERRORCHECK:    检错锁,同一线程对已锁的互斥锁加锁会返回错误

RECURSIVE:       嵌套锁,允许同一线程多次锁定而不产生死锁,多次释放才能被别的线程锁定

DEFAULT:           默认为普通锁,排队获取锁

创建互斥锁

pthread_mutex_init(pthread_mutex_t  *mutex, pthread_mutexattr_t  *attr)

注意:

attr == NULL 初始化的线程锁 mutex

等价于 mutex = PTHREAD_MUTEX_INITIALIZER

互斥锁加锁

pthread_mutex_lock(pthread_mutex_t  *mutex)

对互斥锁加锁

同一线程内对已经加锁的互斥锁,进行再次加锁,会造成死锁

互斥锁解锁

pthread_mutex_unlock(pthread_mutex_t  *mutex)

释放互斥锁

对未锁定的互斥锁,进行释放操作,会产生不确定的行为

尝试解除有其他线程创建的互斥锁,会产生不确定的行为

pthread_mutex_trylock(pthread_mutex_t  *mutex)

试图锁住互斥体,不阻塞

1: 互斥体未上锁,锁定并返回成功

2: 互斥体已经上锁,不阻塞直接返回失败

3: 锁类型为嵌套锁 RECURSIVE,  已上锁,则锁计数器自加

问题:若使用man无法查询文档?pthread_mutex_*  函数族 man 无显示解决办法

解决方式:$ sudo apt-get install manpages-posix-dev

例子:利用互斥锁,两个子进程分开输出50的奇偶数

pthread_mutex_t  mutex;

int g_num=50;

void *threadEven(void *lParam)

{

//加锁

pthread_mutex_lock(&mutex);

while(g_num>0)

{

if(!(g_num&1))

{

printf("even:%d\n",g_num);

}

g_num--;

usleep(1);

}

g_num=50;

//解锁

pthread_mutex_unlock(&mutex);

return NULL;

}

void *threadOdd(void *lParam)

{

//加锁

pthread_mutex_lock(&mutex);

while(g_num>0)

{

if(g_num&1)

{

printf("odd:%d\n",g_num);

}

g_num--;

usleep(1);

}

g_num=50;

//解锁

pthread_mutex_unlock(&mutex);

return NULL;

}

void testMutex()

{

pthread_t thread1,thread2;

//初始化互斥锁

pthread_mutex_init(&mutex,NULL);

int nRet1=pthread_create(&thread1,NULL,threadOdd,NULL);

int nRet2=pthread_create(&thread2,NULL,threadEven,NULL);

printf("thread1 id:%d\t thread2 id:%d\n",(int)thread1,(int)thread2);

if(nRet1||nRet2)

{

fprintf(stderr,"fail to create thread!");

return ;

}

pthread_join(thread1,NULL);

pthread_join(thread2,NULL);

}

int main(int argc,char**argv)

{

testMutex();

return 0;

}

以上是实现,奇偶数分开输出。

ERRORCHECK和RECURSIVE属性:

例子:锁上加锁,ERRORCHECK错误返回

#include<stdio.h>

#include<pthread.h>

#include<stdlib.h>

#include<unistd.h>

#include<string.h>

pthread_mutex_t  mutex;

int g_num=50;

//验证死锁

void *thread()

{

int nRet=pthread_mutex_lock(&mutex);

if(nRet)

{

printf("repeat lock!\n");

return NULL;

}

printf("test:%d\n",g_num);

pthread_mutex_unlock(&mutex);

return NULL;

}

void *threadEven(void *lParam)

{

int nRet=pthread_mutex_lock(&mutex);

if(nRet)

{

printf("repeat lock!\n");

return NULL;

}

while(g_num>0)

{

if(!(g_num&1))

{

printf("even:%d\n",g_num);

}

g_num--;

usleep(1);

}

g_num=50;

thread();

pthread_mutex_unlock(&mutex);

return NULL;

}

void *threadOdd(void *lParam)

{

int nRet=pthread_mutex_lock(&mutex);

if(nRet)

{

printf("repeat lock!\n");

return NULL;

}

while(g_num>0)

{

if(g_num&1)

{

printf("odd:%d\n",g_num);

}

g_num--;

usleep(1);

}

g_num=50;

thread();

pthread_mutex_unlock(&mutex);

return NULL;

}

void testMutex()

{

pthread_t thread1,thread2;

pthread_mutexattr_t  attr;

//设置锁的属性

//pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE);

pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_ERRORCHECK);

//默认排队锁

//pthread_mutex_init(&mutex,NULL);

pthread_mutex_init(&mutex,&attr);

int nRet1=pthread_create(&thread1,NULL,threadOdd,NULL);

int nRet2=pthread_create(&thread2,NULL,threadEven,NULL);

printf("thread1 id:%d\t thread2 id:%d\n",(int)thread1,(int)thread2);

if(nRet1||nRet2)

{

fprintf(stderr,"fail to create thread!");

return ;

}

pthread_join(thread1,NULL);

pthread_join(thread2,NULL);

}

int main(int argc,char**argv)

{

testMutex();

return 0;

}

原文地址:https://www.cnblogs.com/gd-luojialin/p/9216026.html

时间: 2024-10-24 10:20:36

25多线程之互斥锁的相关文章

Linux多线程编程-互斥锁

互斥锁 多线程编程中,(多线程编程)可以用互斥锁(也称互斥量)可以用来保护关键代码段,以确保其独占式的访问,这有点像二进制信号量.POSIX互斥锁相关函数主要有以下5个: #include <pthread.h> int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr); int pthread_mutex_destroy(pthread_mutex_t *mutex); int p

多线程之互斥锁(By C++)

首先贴一段win32API实现的多线程的代码,使用CreateThread实现,如果不要传参数,就把第四个参数设为NULL #include<Windows.h> #include<iostream> using namespace std; //有参数 DWORD WINAPI MyThread_lpParamter(LPVOID lpParamter) { string *lp = (string *)lpParamter; while (1) { cout <<

多线程之互斥锁、条件变量

多线程 一个进程在同一时刻只能做一件事,而多个线程却可以同时执行,每个线程处理各自独立的任务.多线程有很多好处: 简化处理异步事件的代码 实现内存和文件描述符的共享 改善程序的吞吐量 改善响应时间 互斥锁 互斥锁:互斥锁通过锁机制来实现线程间的同步,在同一时刻通常只允许一个关键部分的代码 当多个线程控制相同的内存时,对于读写操作的时间差距就有可能会导致数据的不同步,下图就很清晰的说明了这种情况: 对于线程A.B此时对同一块内存进行操作,但是由于操作几乎是同时进行的,假设当线程A读入数据i之后,在

多线程与互斥锁

线程:线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针.程序计数器等),但代码区是共享的,即不同的线程可以执行同样的函数. 多线程:多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行执行的线程来完成各自的任务. 线程创建 函数原型:int pthread_create(pthread_t*restrict tidp,const pthread_attr_t *restrict attr,void *(*star

多线程的互斥锁的运用

1.互斥锁的初始化pthread_mutex_init()函数语法 2.互斥锁上锁.判断上锁.解锁.销毁锁pthread_mutex_函数语法 代码分析: /* thread_mutex.c */ #include <stdio.h> #include <stdlib.h> #include <pthread.h> #define THREAD_NUMBER 3 /* 线程数 */ #define REPEAT_NUMBER 3 /* 每个线程的任务数 */ #defi

11.python并发入门(part3 多线程与互斥锁)

一.锁的概念. 锁,通常被用来实现共享数据的访问,为每一个共享的数据,创建一个Lock对象(一把锁),当需要访问这个共享的资源时,可以调用acquire方法来获取一个锁的对象,当共享资源访问结束后,在调用release方法去解锁. 二.python中的互斥锁. 在介绍互斥锁之前,先来一起看一个例子.(每个线程对num实现一次-1的操作) import threading import  time num = 200  #每个线程都共享这个变量. tread_list = [] def count

Java多线程系列--“JUC锁”02之 互斥锁ReentrantLock

ReentrantLock介绍 ReentrantLock是一个可重入的互斥锁,又被称为"独占锁". 顾名思义,ReentrantLock锁在同一个时间点只能被一个线程锁持有:而可重入的意思是,ReentrantLock锁,可以被单个线程多次获取.ReentrantLock分为"公平锁"和"非公平锁".它们的区别体现在获取锁的机制上是否公平."锁"是为了保护竞争资源,防止多个线程同时操作线程而出错,ReentrantLock在

【黑马】程序员————多线程(二)单例设计模式、线程间通信,JDK1.5互斥锁

------Java培训.Android培训.iOS培训..Net培训.期待与您交流!----- 一.单例设计模式 单例设计模式的意义: A.保证类在内存中只有一个对象,不提供外部访问方式,构造函数用private修饰. B.提供公共方法(static修饰,类的静态方法),获取类的实例.单例设计模式分为饿汉和懒汉两种模式. 饿汉式&懒汉式 class Test33 { public static void main(String[] args) { Fanjianan.getInstance()

Linux多线程的使用一:互斥锁

多线程经常会在Linux的开发中用到,我想把平时的使用和思考记录下来,一是给自己做个备忘,二是分享给可能会用到的人. POSIX标准下互斥锁是pthread_mutex_t,与之相关的函数有: 1 int pthread_mutex_init(pthread_mutex_t * mutex , pthread_mutexattr_t * attr); 2 int pthread_mutex_destroy (pthread_mutex_t * mutex); 3 int pthread_mute