目录
1、什么是线程
线程是轻量级进程。线程可以对进程的内存空间和资源进行访问,并与同一进程中的其他线程共享。
一个进程可以拥有多个线程,其中每个线程共享该进程所拥有的资源。要注意的是,由于线程共享了进程的资源和地址空间,因此,任何线程对系统资源的操作都会给其他线程带来影响。由此可知,多线程中的同步是非常重要的问题。
2、什么时候用多线程,什么时候用多进程
1、创建和销毁较频繁使用线程,因为创建进程花销大。
2、需要大量数据传送使用线程,一i那位多线程切换速度快,不需要跨越进程边界。
3、安全稳定选进程;快速频繁选线程。
3、线程相关函数
3.1创建线程
一个指向函数的指针,该函数有一个整型参数并返回一个整型数;
数组的类型
int arr[5];---->int [5]
函数的类型 返回值(参数类型)
int a(int);
int (*p)(int); 函数代替的是函数的首地址
p=a;
#include<pthread.h>
int pthread_create(pthread_t *thread,const pthread_attr_t *attr,void *(*start_routine)(void *),void *arg);
参数1 pthread_t *
参数2 线程的属性一般设置为NULL;
参数3 函数的指针 void *(void *)
参数4 主线程给子线程传值 设置为NULL
编译时要连接pthread库
例:
创建线程1 播放音乐
创建线程2 打篮球
void *thread1(void *arg)
{
int i = 0;
while(1)
{
if(i>5)
{
//线程的主动退出
//参数为NULL表示该线程退出时不带出来值
pthread_exit(NULL);
}
printf("play music\n");
sleep(1);
i++;
}
}
void *thread2(void *arg)
{
while(1)
{
printf("play basket\n");
sleep(1);
}
}
3.2等待子线程结束
#include<pthread.h>
int pthread_join(pthread_t thread,void **retval);
参数1 pthread_t
参数2 子线程给主线程传值 NULL
#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
/************************************************/
/*******************线程退出*********************/
/**********************************************/
//void *(void *)返回值 void * 参数 void *
void *thread1(void *arg)
{
int i = 0;
while(1)
{
printf("play music\n");
sleep(1);
}
}
void *thread2(void *arg)
{
while(1)
{
printf("play basket\n");
sleep(1);
}
}
int main(int argc, const char *argv[])
{
//创建线程1
//参数1 pthread_t *
//参数2 线程的属性 一般设置为空
//参数3 函数的指针 (函数名) void * (void*)
//参数4 主线程给子线程通过该参数传值
pthread_t pid1,pid2;
pthread_create(&pid1,NULL,thread1,NULL);
//创建线程2
pthread_create(&pid2,NULL,thread2,NULL);
//等待子线程结束
pthread_join(pid1,NULL);
pthread_join(pid2,NULL);
return 0;
}
3.3线程退出
3.3.1主动退出
#include<pthread.h>
void pthread_exit(void *retval);
参数:NULL,线程退出时不带值
void *thread1(void *arg)
{
int i = 0;
while(1)
{
if(i>5)
{
//线程的主动退出
//参数为NULL表示该线程退出时不带出来值
pthread_exit(NULL);
}
printf("play music\n");
sleep(1);
i++;
}
}
3.3.2被动退出
#include<pthread.h>
int pthread_cancel(pthread_t thread);
参数:线程的ID号
int j = 0;
while(1)
{
if(j>10)
{
//线程被被动取消
//参数 线程的ID号
pthread_cancel(pid2);
}
printf("main process\n");
sleep(1);
j++;
}
#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
/****************************************************/
/***********************线程退出*********************/
/****************************************************/
//void *(void *)返回值 void * 参数 void *
void *thread1(void *arg)
{
int i = 0;
while(1)
{
if(i>5)
{
//线程的主动退出
//参数为NULL表示该线程退出时不带出来值
pthread_exit(NULL);
}
printf("play music\n");
sleep(1);
i++;
}
}
void *thread2(void *arg)
{
while(1)
{
printf("play basket\n");
sleep(1);
}
}
int main(int argc, const char *argv[])
{
//创建线程1
//参数1 pthread_t *
//参数2 线程的属性 一般设置为空
//参数3 函数的指针 (函数名) void * (void*)
//参数4 主线程给子线程通过该参数传值
pthread_t pid1,pid2;
pthread_create(&pid1,NULL,thread1,NULL);
//创建线程2
pthread_create(&pid2,NULL,thread2,NULL);
int j = 0;
while(1)
{
if(j>10)
{
//线程被被动取消
//参数 线程的ID号
pthread_cancel(pid2);
}
printf("main process\n");
sleep(1);
j++;
}
pthread_join(pid1,NULL);
pthread_join(pid2,NULL);
return 0;
}
4、验证线程中全局变量和堆区的数据是共享的
#include<stdio.h>
#include<pthread.h>
/****************************************************/
/*************验证线程中全局变量是共享的*************/
/****************************************************/
int a = 10;
void * thread1(void * arg)
{
a+=10;
printf("thread1 a = %d\n",a);
}
void * thread2(void * arg)
{
a+=20;
printf("thread2 a = %d\n",a);
}
int main(int argc, const char *argv[])
{
pthread_t pid1,pid2;
pthread_create(&pid1,NULL,thread1,NULL);
pthread_create(&pid2,NULL,thread2,NULL);
a+=15;
printf("main thread a = %d\n",a);
pthread_join(pid1,NULL);
pthread_join(pid2,NULL);
return 0;
}
运行结果:
main thread a = 25
thread1 a = 35
thread2 a = 55
#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<string.h>
/****************************************************/
/************验证线程中堆区的数据是共享的************/
/****************************************************/
char *pc = NULL; //pc 全局变量
void *thread1(void * arg)
{
strcat(pc,"i am thread1 ");
printf("thread1:%s\n",pc);
}
void *thread2(void * arg)
{
strcat(pc,"i am thread2 ");
printf("thread2:%s\n",pc);
}
int main(int argc, const char *argv[])
{
pc = (char *)malloc(sizeof(char)*100); //堆区
if(NULL == pc)
{
perror("malloc error");
return -1;
}
memset(pc,0,100);
pthread_t pid1,pid2;
pthread_create(&pid1,NULL,thread1,NULL);
pthread_create(&pid2,NULL,thread2,NULL);
strcat(pc,"i am thread ");
printf("main:%s\n",pc);
pthread_join(pid1,NULL);
pthread_join(pid2,NULL);
free(pc);
pc = NULL;
return 0;
}
运行结果:
main:i am thread
thread1:i am thread i am thread1
thread2:i am thread i am thread1 i am thread2