欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 创投人物 > day30线程

day30线程

2025/2/24 3:59:51 来源:https://blog.csdn.net/luochen330x/article/details/144490455  浏览:    关键词:day30线程

1、线程概念

1、线程是轻量化的进程,一个进程内可以有多个线程,至少包含一个线程(主线程)。

2、线程的任务调度,创建,销毁的开销都要比进程小。

3、进程之间不共享资源,进程运行空间都是独立的,但是线程共享临界资源。

4、线程是任务调度的最小单位,进程是资源分配的最小单位。

5、多任务并发执行大多数选择多线程,而不是多进程,因为线程占用内存非常少大概8K。

6、多个线程每一个都有自己的id号。

7、线程函数来自于第三方库,-pthread,所以要编译线程库函数需要加上 -pthread

8、多线程编程时,对于临界资源访问时可能有多个线程同时访问,这样会产生数据的错乱,这种现象被称为竞态。

临界资源:全局变量,临界区:访问临界资源的代码。

pyhread_create

 #include <pthread.h>int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
功能:创建子线程的函数
参数1:存储创建的子线程号
参数2:创建时附加的线程属性,默认填NULL
参数3:函数指针,子线程的线程体函数,也是子线程开始运行的地方。
参数4:是线程体函数的参数,如果没有参数填NULL即可。
返回值:成功返回0,失败返回-1,并且线程号不确定。
#include <myhead.h>
int k = 0;//全局变量就是临界资源
void *tang(void *n)
{usleep(9);printf("我是子线程:n = %d\n",*(int *)n);*(int *)n+=88;//访问全局变量的代码就叫临界区k = k+55;}
int main(int argc, const char *argv[])
{pthread_t tid;//定义一个线程号变量int n=100;if(pthread_create(&tid,NULL,tang,&n)!=0){perror("pthread_create");return -1;}usleep(90);printf("子线程线程号:%ld\n",tid);printf("主线程中k = %d\tn = %d\n",k,n);//k=55,n=188return 0;
}

2.线程间;数据传递

全局变量:子、主线程共享全局变量资源

#include <myhead.h>
int n = 100;
void *fun()//线程体函数
{sleep(1);//等待一秒n = n+20;printf("子线程中n = %d\n",n);//170
}
int main(int argc, const char *argv[])
{pthread_t tid;if(pthread_create(&tid,NULL,fun,NULL)==-1){perror("pthread_create");return -1;}n = n+50;printf("主线程中n = %d \n",n);//150sleep(2);return 0;
}

2.局部变量作为参数地址传递,子主线程共享局部变量的资源

#include <myhead.h>
void *fun(void *n)//线程体函数
{sleep(1);//等待一秒*(int *)n+=20;printf("子线程中n = %d\n",*(int *)n);//170
}
int main(int argc, const char *argv[])
{pthread_t tid;int n = 100;if(pthread_create(&tid,NULL,fun,&n)==-1){perror("pthread_create");return -1;}n = n+50;printf("主线程中n = %d \n",n);//150sleep(2);return 0;
}

3.结构体

#include <myhead.h>typedef struct
{int id;char name[20];float score;
}stu;
void *task(void *a)//线程体函数
{sleep(1);stu *p = (stu *)a;//强制转换成具体的类型p->id = 1008;
}
int main(int argc, const char *argv[])
{pthread_t tid;stu a = {1001,"黑狗",98.5};if(pthread_create(&tid,NULL,task,&a)==-1){perror("pthread_create");return -1;}sleep(2);printf("主线程中学号:%d\n",a.id);return 0;
}

pthread_self获取线程号

#include <pthread.h>pthread_t pthread_self(void);功能:获取调用线程的线程号参数:无返回值:返回调用线程的线程号。
#include <myhead.h>void *task(void *a)//线程体函数
{printf("子线程中自己的ID  =%ld\n",pthread_self());//输出调用线程自己的ID
}
int main(int argc, const char *argv[])
{pthread_t tid;if(pthread_create(&tid,NULL,task,NULL)==-1){perror("pthread_create");return -1;}sleep(2);printf("主线程中子线的ID = %ld\n",tid);
//输出子线程的IDprintf("主线程中自己的ID = %ld\n",pthread_self());//主线程获取自己的IDreturn 0;
}

pthread_exit线程退出

#include <pthread.h>void pthread_exit(void *retval);功能:退出调用线程参数:任意类型的变量,存储检索后的内容。返回值:无

#include <myhead.h>void *task(void *a)//线程体函数
{sleep(1);printf("子线程中自己的ID  =%ld\n",pthread_self());pthread_exit(NULL);//线程退出函数//exit(0);//整个进程退出while(1);
}
int main(int argc, const char *argv[])
{pthread_t tid;if(pthread_create(&tid,NULL,task,NULL)==-1){perror("pthread_create");return -1;}sleep(2);printf("主线程中子线的ID = %ld\n",tid);printf("主线程中自己的ID = %ld\n",pthread_self());while(1);return 0;
}

6、pthread_join/pthread_detach线程回收和挂起

#include <pthread.h>int pthread_join(pthread_t thread, void **retval);功能:阻塞回收子线程的资源。参数1:要退出的线程号参数2:线程退出时的状态,一般不接收填NULL。返回值:成功返回0,失败返回一个错误码。#include <pthread.h>int pthread_detach(pthread_t thread);功能:非阻塞将线程设置为分离态,设置为分离态的线程由系统回收资源。参数:要设置为分离态的线程号返回值:成功返回0,失败返回一个错误码。
#include <myhead.h>void *task(void *a)//线程体函数
{sleep(5);printf("子线程中自己的ID  =%ld\n",pthread_self());pthread_exit(NULL);//线程退出函数
}
int main(int argc, const char *argv[])
{pthread_t tid;if(pthread_create(&tid,NULL,task,NULL)==-1){perror("pthread_create");return -1;}//pthread_join(tid,NULL);//主线程阻塞回收子线程的资源pthread_detach(tid);//非阻塞将子线程设置为分离态//printf("子线程资源已经被回收\n");printf("子线程成功设置为分离态\n");return 0;
}

验证设置为分离态的子线程是否共享主线程资源:依然共享资源。

#include <myhead.h>
//现将子线程设置为分离态,验证设置为分离态的子线程是否共享主线程资源
int n = 100;
void *task(void *a)//线程体函数
{sleep(2);printf("n = %d\n",n);while(1);
}
int main(int argc, const char *argv[])
{pthread_t tid;if(pthread_create(&tid,NULL,task,NULL)==-1){perror("pthread_create");return -1;}pthread_detach(tid);//设置子线程为分离态 n = n+50;    while(1);    return 0;
}

 验证子线程退出后,子线程是否会立即退出:不会立即退出。子线程依赖主进程

#include <myhead.h>
void *task(void *a)//线程体函数
{while(1){printf("我还活着\n");sleep(1);}while(1);
}
int main(int argc, const char *argv[])
{pthread_t tid;if(pthread_create(&tid,NULL,task,NULL)==-1){perror("pthread_create");return -1;}//pthread_detach(tid);//设置子线程为分离态 
:    pthread_exit(NULL);//主线程退出while(1);return 0;
}

作业:多线程实现文件拷贝,线程拷贝一半,线程拷贝另一半,主线程回收子线程资源。

#include <luochen.h>
//1、计算出文件1的大小,创建文件2
//2、创建两个线程函数
//3、将文件名,拷贝的起始位置和拷贝长度传递给线程函数
//4、线程函数调用拷贝函数实现拷贝
typedef struct
{const char *src;//源文件const char *des;//目标文件int start;//拷贝的起始位置int len;//拷贝的长度
}file_st;int file_length(const char *p1,const char *p2)
{int fd1 = open(p1,O_RDONLY);//只读方式打开文件1if(fd1==-1){perror("open");return -1;}int len = lseek(fd1,0,SEEK_END);int fd2 = open(p2,O_CREAT|O_TRUNC|O_WRONLY,0664);if(fd2==-1){perror("open");return -1;}close(fd1);close(fd2);return len;//返回文件1的大小}
int copy_file(const char *p1,const char *p2,int start,int len)
{int fd1,fd2;if((fd1 = open(p1,O_RDONLY))==-1){perror("open");return -1;}if((fd2 = open(p2,O_WRONLY))==-1){perror("open");return -1;}lseek(fd1,start,SEEK_SET);lseek(fd2,start,SEEK_SET);int sum=0;char buff[100];while(1){int res = read(fd1,buff,sizeof(buff));sum+=res;if(res==0||sum>=len){write(fd2,buff,res-(sum-len));break;}write(fd2,buff,res);}close(fd1);close(fd2);return 0;
}void *fun1(void *p)
{file_st *fi = (file_st *)p;copy_file(fi->src,fi->des,fi->start,fi->len);//调用拷贝函数
}
void *fun2(void *p)
{file_st *fi = (file_st *)p;copy_file(fi->src,fi->des,fi->start,fi->len);//调用拷贝函数
}
int main(int argc, const char *argv[])
{if(argc!=3){printf("外部传参错误\n");return -1;}int len = file_length(argv[1],argv[2]);//算出文件1的大小,创建文件2file_st a = {argv[1],argv[2],0,len/2};file_st b = {argv[1],argv[2],len/2,len-len/2};pthread_t tid1,tid2;if(pthread_create(&tid1,NULL,fun1,&a)==-1)//调用子线程1拷贝文件{perror("pthread_create");return -1;}if(pthread_create(&tid2,NULL,fun2,&b)==-1)//调用子线程2拷贝文件{perror("pthread_create");return -1;}pthread_join(tid1,NULL);pthread_join(tid2,NULL);//阻塞回收子线程的资源return 0;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词