线程详解(3+4+5)

一、进程与线程的区别(面试会问)

  1. 进程在创建时,会建立很多的数据表来维护我们的代码段。也就是为进程分配所需要的内存,与线程相比就显得很“大方”——开销大。而进程只是线程的一个容器,“寄生”于进程。
  2. 进程拥有独立的地址空间,数据不共享。如果在进程间传递数据就需要用到进程间通信,调用许多的API来实现数据的传递;而线程是共享数据空间,在进行数据交换的时候就显得十分的方便。

二、线程

1.创建线程

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);

2.线程退出

void pthread_exit(void *retval);

3.线程等待

int pthread_join(pthread_t thread, void **retval);

4.实例代码

创建两个线程:

#include<stdio.h>
#include<pthread.h>

void* func(void* arg)
{
	static int ret=10;
	printf("func:my pthread is %ld\n",(unsigned long)pthread_self());
	printf("func:%d\n",*((int*)arg));
	pthread_exit((void*)&ret);
}

void* func1(void* arg)
{
	static int ret=10;
	printf("func1:my pthread is %ld\n",(unsigned long)pthread_self());
	printf("func1:%d\n",*((int*)arg));
	pthread_exit((void*)&ret);
}
int main()
{
//int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
//                          void *(*start_routine) (void *), void *arg);

	pthread_t thread;
	pthread_t thread1;
	int ret;
	int ret1;
	int arg=100;
	int* pret;
	int* pret1;
	ret=pthread_create(&thread,NULL,&func,(void*)&arg);
	if(ret!=0){
		printf("create pthread failed!\n");
	}
	printf("create pthread ok!\n");
	printf("main: my pthread is %ld\n",(unsigned long)pthread_self());
	pthread_join(thread,(void**)&pret);
	printf("main:ret %d\n",*pret);
	printf("\n");
	ret1=pthread_create(&thread1,NULL,&func1,(void*)&arg);
	if(ret1!=0){
		printf("create pthread failed!\n");
	}
	printf("create pthread ok!\n");
	printf("main: my pthread is %ld\n",(unsigned long)pthread_self());
	pthread_join(thread,(void**)&pret1);//二级指针指向ret的值
	printf("main:ret1 %d\n",*pret1);
	return 0;
}

三、互斥锁(线程间通信)

1.初始化互斥锁

(1).互斥锁的动态初始化

int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
mutex:互斥锁
attr:互斥锁属性,NULL表示为默认属性

(2).互斥锁静态初始化

pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER

2.销毁互斥锁

int pthread_mutex_destroy(pthread_mutex_t *mutex);

3.加锁

int pthread_mutex_lock(pthread_mutex_t *mutex);

4.解锁

int pthread_mutex_unlock(pthread_mutex_t *mutex);

5.示例代码:

#include<stdio.h>
#include<pthread.h>


pthread_mutex_t mutex;
void* func(void* arg)
{
	pthread_mutex_lock(&mutex);
	static int ret=10;
	printf("func:my pthread is %ld\n",(unsigned long)pthread_self());
	printf("func:%d\n",*((int*)arg));
	pthread_mutex_unlock(&mutex);
	pthread_exit((void*)&ret);

}

void* func1(void* arg)
{
	pthread_mutex_lock(&mutex);

	static int ret=10;
	printf("func1:my pthread is %ld\n",(unsigned long)pthread_self());
	printf("func1:%d\n",*((int*)arg));
	pthread_mutex_unlock(&mutex);
	pthread_exit((void*)&ret);
}
int main()
{
//int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
//                          void *(*start_routine) (void *), void *arg);

	pthread_t thread;
	pthread_t thread1;
	int ret;
	int ret1;
	int arg=100;
	int* pret;
	int* pret1;
//int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
	pthread_mutex_init(&mutex,NULL);//before create pthread
	ret=pthread_create(&thread,NULL,&func,(void*)&arg);
	if(ret!=0){
		printf("create pthread failed!\n");
	}
	printf("create pthread ok!\n");
	printf("main: my pthread is %ld\n",(unsigned long)pthread_self());
	pthread_join(thread,(void**)&pret);
	printf("main:ret %d\n",*pret);
	printf("\n");
	ret1=pthread_create(&thread1,NULL,&func1,(void*)&arg);
	if(ret1!=0){
		printf("create pthread failed!\n");
	}
	printf("create pthread ok!\n");
	printf("main: my pthread is %ld\n",(unsigned long)pthread_self());
	pthread_join(thread,(void**)&pret1);
	printf("main:ret1 %d\n",*pret1);
	return 0;
}

使用互斥锁对临界资源的访问

#include<stdio.h>
#include<pthread.h>
int data=0;//临界资源

pthread_mutex_t mutex;
void* func(void* arg)
{
	static int ret=10;
	printf("func:my pthread is %ld\n",(unsigned long)pthread_self());
	printf("func:%d\n",*((int*)arg));
	sleep(1);
	pthread_mutex_lock(&mutex);
	while(1){
		printf("func:data=%d\n",data++);
		if(data==3){//当data==3才退出
		printf("func:data=%d\n",data);
		pthread_mutex_unlock(&mutex);
		pthread_exit((void*)&ret);
		}
	}

}

void* func1(void* arg)
{
	static int ret=10;
	printf("func1:my pthread is %ld\n",(unsigned long)pthread_self());
	printf("func1:%d\n",*((int*)arg));
	while(1){
		printf("func1:data=%d\n",data);
		pthread_mutex_lock(&mutex);
		data++;
		pthread_mutex_unlock(&mutex);
		//pthread_exit((void*)&ret);
		sleep(1);
	}

}
int main()
{
//int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
//                          void *(*start_routine) (void *), void *arg);

	pthread_t thread;
	pthread_t thread1;
	int ret;
	int ret1;
	int arg=100;
	int* pret;
	int* pret1;
//int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
	pthread_mutex_init(&mutex,NULL);//before create pthread
	ret=pthread_create(&thread,NULL,&func,(void*)&arg);
	if(ret!=0){
		printf("create pthread failed!\n");
	}
	printf("create pthread ok!\n");
	printf("main: my pthread is %ld\n",(unsigned long)pthread_self());
	pthread_join(thread,(void**)&pret);
	printf("main:ret %d\n",*pret);
	printf("\n");
	ret1=pthread_create(&thread1,NULL,&func1,(void*)&arg);
	if(ret1!=0){
		printf("create pthread failed!\n");
	}
	printf("create pthread ok!\n");
	printf("main: my pthread is %ld\n",(unsigned long)pthread_self());
	while(1);{
		printf("main:data=%d\n",data);
		sleep(1);
	}
	pthread_join(thread,(void**)&pret1);
	printf("main:ret1 %d\n",*pret1);
	return 0;
}

四、什么情况会造成死锁(面试会问)

死锁的情况一般发生在至少有两个锁的状态下。当A进程持有一个锁1时,同时持有锁2,但是B进程此时持有锁2,同时也想持有锁1。此时就发生互相等待对方导致进程阻塞呈现一个僵持的局面,谁也无法往下执行。

五、条件变量(一般和互斥锁配合使用)

1.条件变量初始化

int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
//函数参数一配置为初始化值的地址
//参数二用默认的方式初始化,restrict attr,一般配置为NULL

2.等待一个条件变量

int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
//参数一:同上。
//参数二 :即为锁,这个锁用来解开唤醒这个条件变量的所控制的线程,可以解开这个锁,

3.唤醒条件变量

int pthread_cond_signal(pthread_cond_t *cond);

4.销毁条件变量

int pthread_cond_destroy(pthread_cond_t *cond)

5.唤醒所有条件变量

int pthread_cond_broadcast(pthread_cond_t *cond)

6.示例代码:

#include<stdio.h>
#include<pthread.h>

int data=0;
pthread_mutex_t mutex;
pthread_cond_t cond;
void* func(void* arg)
{
	//static int ret=10;
	//printf("func:my pthread is %ld\n",(unsigned long)pthread_self());
	printf("func:%d\n",*((int*)arg));
	while(1){
// int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
	pthread_cond_wait(&cond,&mutex);
	printf("this is for func!\n");
	printf("data=%d\n",data);
	data=0;
	sleep(1);	
	}
	//pthread_exit((void*)&ret);

}

void* func1(void* arg)
{
	//static int ret=10;
	//printf("func1:my pthread is %ld\n",(unsigned long)pthread_self());
	printf("func1:%d\n",*((int*)arg));
	while(1){
	pthread_mutex_lock(&mutex);
	data++;
	printf("func1:data = %d\n",data);
	if(data==3){
		pthread_cond_signal(&cond);
	}
	pthread_mutex_unlock(&mutex);
	sleep(1);
	
	//pthread_exit((void*)&ret);
	}
}
int main()
{
//int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
//                          void *(*start_routine) (void *), void *arg);

	pthread_t thread;
	pthread_t thread1;
	int ret;
	int ret1;
	int arg=100;
	int* pret;
	int* pret1;
//int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr)
//int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
	pthread_cond_init(&cond,NULL);
	pthread_mutex_init(&mutex,NULL);//before create pthread
	ret=pthread_create(&thread,NULL,&func,(void*)&arg);
	if(ret!=0){
		printf("create pthread failed!\n");
	}
	printf("create pthread ok!\n");
	//printf("main: my pthread is %ld\n",(unsigned long)pthread_self());
	//printf("main:ret %d\n",*pret);
	printf("\n");
	ret1=pthread_create(&thread1,NULL,&func1,(void*)&arg);
	if(ret1!=0){
		printf("create pthread failed!\n");
	}
	printf("create pthread ok!\n");
	//printf("main: my pthread is %ld\n",(unsigned long)pthread_self());
	pthread_join(thread,NULL);
	pthread_join(thread1,NULL);
	//printf("main:ret1 %d\n",*pret1);
	pthread_mutex_destroy(&mutex);
	pthread_cond_destroy(&cond);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值