Day 3.线程的分离属性、互斥、*死锁的和信号量

一、线程的分离属性

线程结束后,自动回收线程空间

1. pthread_attr_init

int pthread_attr_init(pthread_attr_t *attr);

功能:线程属性初始化

2. pthread_attr_destroy

int pthread_attr_destroy(pthread_attr_t *attr);

功能:线程属性销毁

3. pthread_attr_setdetachstate 

int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);

功能:设置分离属性

PTHREAD_CREATE_DETACHED   分离属性

PTHREAD_CREATE_JOINABLE   加入属性(默认)

示例:

#include "head.h"


void *thread1(void* argc)
{
	printf("线程1(%#x)正在运行...\n",(unsigned int)pthread_self());

	return NULL;
}
void *thread2(void* argc)
{
	printf("线程2(%#x)正在运行...\n",(unsigned int)pthread_self());

	return NULL;
}
void *thread3(void* argc)
{
	printf("线程3(%#x)正在运行...\n",(unsigned int)pthread_self());

	return NULL;
}

int main(void)
{
	pthread_t pid[3];
	void*(*p[3])(void *) = {thread1,thread2,thread3};

	int i = 0;
	pthread_attr_t attr;                     //创建一个线程属性变量

	pthread_attr_init(&attr);                //对线程属性初始化
	pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);             //定义为分离属性

	for (i = 0; i < 3; ++i)
	{
		pthread_create(&pid[i],&attr,p[i],NULL);
	}

	pthread_attr_destroy(&attr);         //回收销毁掉线程属性
	while(1)
	{

	}

	return 0;
}

二、线程互斥

1.互斥锁:(多线程操作全局变量时加锁)

防止资源竞争

2.函数接口:

1)pthread_mutex_init;

int pthread_mutex_init(pthread_mutex_t *restrict mutex,

                                   const pthread_mutexattr_t *restrict attr);

功能:互斥锁初始化

参数:

mutex:互斥锁空间首地址

attr:互斥锁的属性(默认为NULL)

返回值:成功返回0;失败返回错误码

2)pthread_mutex_destroy;

int pthread_mutex_destroy(pthread_mutex_t *mutex);

功能:互斥锁销毁

参数:

mutex:互斥锁空间首地址

返回值:成功返回0;失败返回错误码

3)pthread_mutex_lock;

int pthread_mutex_lock(pthread_mutex_t *mutex);

功能:上锁

参数:锁的地址

4)pthread_mutex_unlock:

int pthread_mutex_unlock(pthread_mutex_t *mutex);

功能:解锁

参数:锁的地址

3、临界资源、临界区

加锁解锁中间的代码成为临界资源、临界区

同一时刻临界资源不能同时执行,只能执行其中一个临界代码

4、原子操作

CPU最小的一次不能被任务调度打断的操作称为原子操作

5、互斥锁的特点

互斥锁只能解决资源竞争的问题;不能解决同步的问题

示例:

#include "head.h"

pthread_mutex_t lock;          //定义一个互斥锁的类型 命名为lock
int num = 0;

void *thread1(void *arg)
{
	while(1)
	{
		pthread_mutex_lock(&lock);     //上锁
		num = 100;
		pthread_mutex_unlock(&lock);   //解锁
	}

	return NULL;
}

void *thread2(void *arg)
{
	while(1)
	{
		pthread_mutex_lock(&lock);
		num = 200;
		printf("num = %d\n",num);
		pthread_mutex_unlock(&lock);
	}

	return NULL;
}

int main(void)
{
	pthread_t tid1;
	pthread_t tid2;

	pthread_mutex_init(&lock,NULL);       //对互斥锁初始化

	pthread_create(&tid1,NULL,thread1,&num);
	pthread_create(&tid2,NULL,thread2,&num);

	pthread_join(tid1,NULL);
	pthread_join(tid2,NULL);
	pthread_mutex_destroy(&lock);   //销毁互斥锁

	return 0;
}
打印结果全是:num=200
注意:两个线程的临界代码都要上锁
原因:宏观并行;微观串行

三、死锁

多线程操作互斥锁,导致多个线程均无法向下执行的状态成为死锁状态简称死锁

1.死锁产生的四个必要条件:

1)互斥条件

2)不可剥夺条件

3)请求保持

4)循环等待

2.避免产生死锁:

1)pthread_mutex_trylock(尝试加锁)替代 pthread_mutex_lock 

2)加锁顺序保持一致

四、信号量

信号量时一种资源,可以被初始化、申请、释放、销毁。

p操作:申请资源

v操作:释放资源

1.sem_init  

int sem_init(sem_t *sem, int pshared, unsigned int value);

功能:初始化信号量

参数:

sem:信号量空间首地址

pshared:0  一个进程中所有线程共享

                非0  进程间共享

返回值:

成功返回0 

失败返回-1

2.sem_destroy:

int sem_destroy(sem_t *sem);

功能:信号量的销毁

参数:

sem:信号量空间首地址

返回值:成功放回0;失败返回-1

3.sem_wait:

int sem_wait(sem_t *sem);

功能:申请信号量

4.sem_post:

int sem_post(sem_t *sem);

功能:释放信号量

示例:

#include "head.h"

char tempuff[4096] = {0};
sem_t sem_w;      //定义一个资源量类型的写变量
sem_t sem_r;      //定义一个资源量类型的读变量

void *thread1(void *arg)
{
	while(1)
	{
		sem_wait(&sem_w);           //申请一个写信号
		gets(tempuff);
		sem_post(&sem_r);           //释放一个读信号
	}

	return NULL;
}

void *thread2(void *arg)
{
	while(1)
	{
		sem_wait(&sem_r);        //申请一个读信号
		printf("tempuff = %s\n",tempuff);
		sem_post(&sem_w);      //释放一个写信号
	}

	return NULL;
}


int main(void)
{
	pthread_t tid1;
	pthread_t tid2;

	sem_init(&sem_w,0,1);      //对写变量初始化 定义在线程中 给到一个资源
	sem_init(&sem_r,0,0);      //对读变量初始化 定义在线程中 给零个资源

	pthread_create(&tid1,NULL,thread1,NULL);
	pthread_create(&tid2,NULL,thread2,NULL);

	pthread_join(tid1,NULL);
	pthread_join(tid2,NULL);

	sem_destroy(&sem_w);   //销毁写
	sem_destroy(&sem_r);   //销毁读

	return 0;
}
作用:能用来保持多线程中保持程序的同步性;一个执行、一个等待,依次运行。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我爱敲代码yx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值