多线程的三大类基本操作
(一)线程概念
线程是指运行中的程序的调度单位。一个线程指的是进程中一个单一顺序的控制流,也被称为轻量级线程。它是系统独立调度和分配的基本单位。同一进程中的多个线程将共享该系统中的全部系统资源,比如文件描述符和信号处理等。一个进程可以有很多线程,每个线程并行执行不同的任务。
(二)线程与进程比较
① 和进程相比,它是一种非常“节俭”的多任务操作方式。在Linux系统中,启动一个新的进程必须分配给它独立的地址空间,建立众多的数据表来维护其代码段、堆栈段和数据段,这种多任务工作方式的代价非常“昂贵”。而运行于一个进程中的多个线程,它们彼此之间使用相同的地址空间,共享大部分数据,启动一个线程所花费的空间远远小于启动一个进程所花费的空间,而且线程间彼此切换所需要时间也远远小于进程间切换所需要的时间。
② 线程间方便的通信机制。对不同进程来说它们具有独立的数据空间,要进行数据的传递只能通过通信的方式进行。这种方式不仅费时,而且很不方便。线程则不然,由于同一进程下的线程之间共享数据空间,所以一个线程的数据可以直接为其他线程所用,不仅方便,而且快捷。
(三)线程基本编程
Linux系统下的多线程遵循POSIX线程接口,称为pthread。编写Linux下的多线程程序,需要使用头文件pthread.h,连接时需要使用库libpthread.a。因为pthread的库不是Linux系统的库,所以在编译时要加上 -lpthread。例如:gcc filename -lpthread。注意,这里要讲的线程相关操作都是用户空间中的线程的操作。
(上面这些概念借鉴其他博主看下面的demo吧)
一、线程的创建、等待、退出
#include<stdio.h>
#include<pthread.h>
// int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
// void *(*start_routine) (void *), void *arg);
void *fun1(void *arg)
{
static int ret=10;
printf("t :%ld thread is creat \n",(unsigned long)pthread_self());
printf("t :param is %d\n",*((int *)arg));
pthread_exit((void *)&ret); //退出
}
int main()
{
int ret;
int *pret=NULL;
int param=100;
pthread_t t;
ret=pthread_create(&t,NULL,fun1,(void *)¶m); //创建
if(ret==0){
printf("main :create t success\n");
}
printf("man :%ld\n ",(unsigned long)pthread_self());
pthread_join(t,(void **)&pret); //等待
printf("main t quit :%d\n",*pret);
return 0;
}
二、线程共享内存空间
#include<stdio.h>
#include<pthread.h>
int g_data=0;
void *fun1(void *arg)
{
printf("t1:%ld thread is create \n",(unsigned long)pthread_self());
printf("t1:param is %d\n",*((int *)arg));
while(1){
printf("t1 :%d\n",g_data++);
sleep(1);
}
}
void *fun2(void * arg)
{
printf("t2 :%ld thread is create\n",(unsigned long)pthread_self());
printf("t2 :param is %d\n",*((int*)arg));
while(1){
printf("t2:%d\n",g_data++);
sleep(1);
}
}
int main()
{
int ret;
int param =100;
pthread_t t1;
pthread_t t2;
ret=pthread_create(&t1,NULL,fun1,(void *)¶m);
if(ret==0){
printf("main :create t1 success\n");
}
ret=pthread_create(&t2,NULL,fun2,(void *)¶m);
if(ret==0){
printf("main :create t2 success\n");
}
printf("main :%ld\n",(unsigned long)pthread_self());
while(1){
printf("main :%d\n",g_data++);
sleep(1);
}
pthread_join(t1,NULL);
pthread_join(t2,NULL);
return 0;
}
运行结果
三、互斥锁限制共享资源的访问、
#include<stdio.h>
#include<pthread.h>
int g_data=0;
pthread_mutex_t mutex; //锁
void *fun1(void *arg)
{
printf("t1:%ld thread is create \n",(unsigned long)pthread_self());
printf("t1:param is %d\n",*((int *)arg));
while(1){
pthread_mutex_lock(&mutex); //上锁
printf("t1 :%d\n",g_data++);
if(g_data==3){
pthread_mutex_unlock(&mutex); //解锁
printf("t1 over\n");
pthread_exit(NULL); //结束t1 的进程
// exit(0); t1同样可以结束整个程序
}
}
}
void *fun2(void * arg)
{
printf("t2 :%ld thread is create\n",(unsigned long)pthread_self());
printf("t2 :param is %d\n",*((int*)arg));
while(1){
printf("t2:%d\n",g_data++);
pthraed_mutex_lock(&mutex); //去拿锁
g_data++;
pthread_mutex_unlock(&mutex); //解锁
sleep(1);
}
}
int main()
{
int ret;
int param =100;
pthread_t t1;
pthread_t t2;
ret=pthread_create(&t1,NULL,fun1,(void *)¶m);
if(ret==0){
printf("main :create t1 success\n");
}
ret=pthread_create(&t2,NULL,fun2,(void *)¶m);
if(ret==0){
printf("main :create t2 success\n");
}
printf("main :%ld\n",(unsigned long)pthread_self());
while(1){
printf("main :%d\n",g_data);
sleep(1);
}
pthread_join(t1,NULL);
pthread_join(t2,NULL);
pthread_mutex_destroy(&mutex);
return 0;
}
运行结果
四、什么情况下造成死锁(多把锁操作时才会出现死锁)
#include<stdio.h>
#include<pthread.h>
int g_data=0;
pthread_mutex_t mutex; //锁1
pthread_mutex_t mutex2; //锁2
void *fun1(void *arg)
{
int i;
pthread_mutex_lock(&mutex);
sleep(1);
pthread_mutex_lock(&mutex2);
for(i=0;i<5;i++)
printf("t1:%ld thread is create\n",pthread_self());
printf("t1: %d param \n",*((int *)arg));
pthread_mutex_unlock(&mutex);
}
void *fun2(void *arg)
{
pthread_mutex_lock(&mutex2);
sleep(1);
pthread_mutex_lock(&mutex);
printf("t2:%ld pthread is create\n",pthread_self());
printf("t2: %d param \n",*((int *)arg));
pthread_mutex_unlock(&mutex);
}
int main()
{
int ret;
int param=100;
pthread_t t1;
pthread_t t2;
pthread_mutex_init(&mutex,NULL);
pthread_mutex_init(&mutex2,NULL);
ret=pthread_create(&t1,NULL,fun1,(void *)¶m);
if(ret==0){
printf("main: pthread create success\n");
}
ret=pthread_create(&t2,NULL,fun2,(void *)¶m);
if(ret==0){
printf("main: pthread create success\n");
}
printf("main :%ld\n",pthread_self());
pthread_join(t1,NULL);
pthread_join(t2,NULL);
pthread_mutex_destroy(&mutex);
pthread_mutex_destroy(&mutex2);
return 0;
}
运行结果
五、线程条件控制实现线程的同步
#include<stdio.h>
#include<pthread.h>
int g_data=0;
pthread_mutex_t mutex;
pthread_cond_t cond;
void *fun1(void *arg)
{
printf("t1:%ld thread is create\n",pthread_self());
printf("t1: %d param \n",*((int *)arg));
pthread_mutex_lock(&mutex);
while(1){
pthread_cond_wait(&cond,&mutex);
printf("-----------t1 run------------\n");
printf("t1:%d\n",g_data);
g_data=0;
sleep(1);
}
}
void *fun2(void *arg)
{
printf("t2:%ld pthread is create\n",pthread_self());
printf("t2: %d param \n",*((int *)arg));
while(1){
printf("t2:%d\n",g_data);
pthread_mutex_lock(&mutex);
g_data++;
if(g_data==3){
pthread_cond_signal(&cond);
}
pthread_mutex_unlock(&mutex);
sleep(1);
}
}
int main()
{
int ret;
int param=100;
pthread_t t1;
pthread_t t2;
pthread_mutex_init(&mutex,NULL);
pthread_cond_init(&cond,NULL);
ret=pthread_create(&t1,NULL,fun1,(void *)¶m);
if(ret==0){
printf("main: pthread create success\n");
}
ret=pthread_create(&t2,NULL,fun2,(void *)¶m);
if(ret==0){
printf("main: pthread create success\n");
}
printf("main :%ld\n",pthread_self());
while(1){
printf("main :%d\n",g_data);
sleep(1);
}
pthread_join(t1,NULL);
pthread_join(t2,NULL);
pthread_mutex_destroy(&mutex);
pthraed_cond_destroy(&cond);
return 0;
}
运行结果