ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

Linux多线程

2021-11-21 23:58:00  阅读:171  来源: 互联网

标签:include int void Linux 线程 pthread 多线程 id


进程和线程的区别有哪些呢?

进程是资源分配的最小单位,线程是CPU调度的最小单位 

进程有自己的独立地址空间,线程共享进程中的地址空间 

进程的创建消耗资源大,线程的创建相对较小

进程的切换开销大,线程的切换开销相对较小 

进程:程序执行的过程叫进程。

线程:进程内部的一条执行序列或执行路径,一个进程可以包含多条线程(多线程)!

每个进程最少有一个线程,例如下面代码:

#include <stdio.h>

int main()
{
    return 0;
}

        虽然只有一个主函数main,主函数的线程又叫主线程,其他的线程都叫它的子线程

下面来认识一下创建线程,退出线程,等待线程这些函数所需的参数以及具体是什么意义

线程的创建:

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

//里面有四个参数
//pthread_t *thread: 接收创建的线程的ID
//attr: 指定线程的属性   一般为NULL
//void *(start_routine)(void *): 其中start_routine指定线程函数  然后前面那个void*就是函数的返回值是void *的,后面括号里的void *就是这个函数的参数是void *类型
//arg: 给线程函数传递的参数(如果上面那个线程函数的参数是void *的话,这块填NULL就好)

线程的等待函数:

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

//pthread_join()等待thread指定的线程退出,线程未退出时,该方法阻塞 
//retval:接收thread线程退出时,指定的退出信息(这块如果没有特殊的返回信息,写NULL就好)

线程的退出函数:

int pthread_exit(void *retval); 

//retval:指定退出信息 

然后下面来写一个简单的代码来实现一下多线程:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<pthread.h> //多线程的创建  等待  退出所需的头文件

void* fun(void* arg)     //线程函数
{
    for(int i = 0 ; i < 3 ; i++)
    {
        printf("fun run!\n");
    }
}

int main()
{
    pthread_t id;  //线程id
    pthread_create(&id,NULL,fun,NULL);  //线程的创建
    for(int i = 0 ; i < 3 ; i++)
    {
        printf("main run");
    }
    
}

上述程序的结果应该是main run和fun run各打印三次  但是结果不尽人意,如下图:

 结果是子线程没有执行,只有主线程,这块就得提一下子线程和主线程的执行顺序----> 并发执行

下面来看一张照片:

 来自于《Linux高性能服务器编程》上的一张照片,上面说了,多线程并发是看起来像“并发”,其实是cpu以时间片作为周期来切换线程来执行,也就是说,在上述代码执行的时候,是主线程在第一个时间片内先抢到了cpu资源,先执行的主线程,然后在第一个时间片内,主线程结束了,进程也就结束了,当然子线程也就不会打印了,这时候上面说到的线程等待函数就派上用场了

还有一位大哥在博客中写的很好,很清楚:

多线程(并发执行)_Bella_chene的博客-CSDN博客_多线程执行

来看下面代码:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<pthread.h> //多线程的创建  等待  退出所需的头文件

void* fun(void* arg)     //线程函数
{
    for(int i = 0 ; i < 3 ; i++)
    {
        printf("fun run!\n");
    }
}

int main()
{
    pthread_t id;  //线程id
    pthread_create(&id,NULL,fun,NULL);  //线程的创建
    for(int i = 0 ; i < 3 ; i++)
    {
        printf("main run");
    }
    
    pthread_join(id,NULL); //id就是指定的线程id   这块的id就是子线程的线程id
                           //这块的NULL是在子线程中没有用篇thread_exit()返回的值
    
}

加上等待函数pthread_join()之后的运行结果也印证了上述时间片的那个说法:

 在第一个时间片内,主函数执行完,之后本来是要结束进程的,但是pthread_join函数这块传入的是子线程的线程id,必须等子线程执行完之后,他才可以结束,要不就储于阻塞状态!

然后还有一个线程退出函数,下面来介绍一下:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<pthread.h> //多线程的创建  等待  退出所需的头文件

void* fun(void* arg)     //线程函数
{
    for(int i = 0 ; i < 3 ; i++)
    {
        printf("fun run!\n");
    }
    
    pthread_exit("fun run over");//这块返回fun run over
}

int main()
{
    pthread_t id;  //线程id
    pthread_create(&id,NULL,fun,NULL);  //线程的创建
    for(int i = 0 ; i < 3 ; i++)
    {
        printf("main run");
    }
    
    char * s= NULL; //将pthread_exit返回的值存储于s中
    pthread_join(id,(void**)&s); //id就是指定的线程id   这块的id就是子线程的线程id
                                 //(void**)&s用来接收线程推出的值
    printf("%s\n",s);
}

附上运行结果:

 pthread_exit()函数的返回值打印在了最后!

这样的话,基本的Linux的多线程基础基本就没了,后面会陆续更新多线程用信号量控制,用互斥锁控制!

奥里给,兄弟们!

标签:include,int,void,Linux,线程,pthread,多线程,id
来源: https://blog.csdn.net/qq_45829112/article/details/121458560

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有