0
点赞
收藏
分享

微信扫一扫

Linux多线程-概念和控制

晚安大世界 2022-04-21 阅读 35

Linux多线程-概念和控制

零、前言

一、Linux线程概念

1、什么是线程

  • 概念:
  • 以整个运行视角理解:
  • 示图:
image-20220328181216490
  • 如何理解之前所说的’进程’:
  • 注意:

2、vfork函数/pthread线程库

  • vfork函数原型:
pid_t vfork(void);
  • 注意:

示例:

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>

int main()
{
    int val=100;
    pid_t id=vfork();
    if(id==0)
    {
        //child
        int cnt=0;
        while(1)
        {
            printf("i am child pid:%d ppid:%d val:%d &val:%p\n",getpid(),getppid(),val,&val);
            cnt++;
            sleep(1);
            if(cnt==2)
                val=200;
            if(cnt==5)
                exit(0);
        }
    }
    else if(id>0)
    {
        //father
        int cnt=0;
        while(1)
        {
            printf("i am father pid:%d ppid:%d val:%d &val:%p\n",getpid(),getppid(),val,&val);
            cnt++;
            sleep(1);
            if(cnt==3)
                val=300;
        }
    }
    return 0;
}
  • 效果:
image-20220330150721687
  • 原生线程库pthread:

3、线程优缺点及其他分析

  • 线程的优点:
  • 注意:
  • 线程的缺点:
  • 线程异常:
  • 线程用途:

二、Linux进程VS线程

1、进程和线程

  • 概念:
  • 线程共享进程数据,但也有线程自己独有的数据:
  • 线程中共享的数据:
  • 进程和线程的关系图:
image-20220330151315969

三、Linux线程控制

1、POSIX线程库

  • pthread线程库是应用层的原生线程库:
  • 错误检查:

2、线程创建

  • pthread_create函数原型:
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg);
  • 解释:
  • 注意:
  • 示例:
mypthread.c:
#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
#include<stdlib.h>
#include<string.h>
int val=0;
void* Routine(void* avgs)
{
    while(1)
    {
        printf("I am %s... val:%d\n",(char*)avgs,val);
        sleep(1);
    }
}
int main()
{
    pthread_t tid1,tid2,tid3;
    int ret1=pthread_create(&tid1,NULL,Routine,(void*)"pthread 1");
    if(ret1!=0)
    {
        fprintf(stderr,"pthread_creat:%s\n",strerror(ret1));
        exit(1);
    }
    int ret2=pthread_create(&tid2,NULL,Routine,(void*)"pthread 2");
    if(ret2!=0)
    {
        fprintf(stderr,"pthread_creat:%s\n",strerror(ret2));
        exit(1);
    }
    int ret3=pthread_create(&tid3,NULL,Routine,(void*)"pthread 3");
    if(ret3!=0)
    {
        fprintf(stderr,"pthread_creat:%s\n",strerror(ret3));
        exit(1);
    }
    while(1)
    {
        printf("I am main pthread...val:%d\n",val++);
        sleep(1);
    }
    return 0;
}
Makefile:
mypthread:mypthread.c
		gcc -o  $@ $^ -pthread 
.PHONY:clean
clean:
		rm -f mypthread
  • 效果:
image-20220330162326544
  • 查看线程信息:ps -aL
image-20220330163055319
  • 注意:

3、线程ID及线程地址空间布局

  • 概念:
  • pthread_ self函数原型:
pthread_t pthread_self(void);
  • 示图:
image-20220330163816548

4、线程终止

  • 终止线程的三种方法:
  • pthread_exit函数原型:
void pthread_exit(void *value_ptr);
  • 解释:
  • pthread_cancel函数原型:
int pthread_cancel(pthread_t thread);
  • 解释:

示例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
void *thread1(void *arg)
{
    printf("%s returning ... \n",(char*)arg);
    int *p = (int*)malloc(sizeof(int));
    *p = 1;
    return (void*)p;
}
void *thread2(void *arg)
{
    printf("%s exiting ...\n",(char*)arg);
    int *p = (int*)malloc(sizeof(int));
    *p = 2;
    pthread_exit((void*)p);
} 
void *thread3(void *arg)
{
    while ( 1 ){ //
        printf("%s is running ...\n",(char*)arg);
        sleep(1);
    } 
    return NULL;
} 
int main( void )
{
    pthread_t tid;
    void *ret;
    // thread 1 return
    pthread_create(&tid, NULL, thread1, (void*)"thread 1");
    pthread_join(tid, &ret);
    printf("thread 1 return, thread id %X, return code:%d\n", tid, *(int*)ret);
    free(ret);
    // thread 2 exit
    pthread_create(&tid, NULL, thread2, (void*)"thread 2");
    pthread_join(tid, &ret);
    printf("thread 2 exit, thread id %X, return code:%d\n", tid, *(int*)ret);
    free(ret);
    // thread 3 cancel by other
    pthread_create(&tid, NULL, thread3, (void*)"thread 3");
    sleep(3);
    pthread_cancel(tid);
    pthread_join(tid, &ret);
    if (ret == PTHREAD_CANCELED)
        printf("thread 3 cancel, thread id %X, return code: PTHREAD_CANCELED->%d\n", tid,ret);
    else
        printf("thread return, thread id %X, return code:%d\n", tid,ret);
    return 0;
}
  • 效果:
image-20220331214538932

5、线程等待

  • 为什么需要线程等待:
  • pthread_join函数原型:
int pthread_join(pthread_t thread, void **value_ptr);
  • 解释:
  • 注意:
  • 终止获取的状态情况:
  • 示图:
image-20220330230231056
  • 示例:
#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
#include<stdlib.h>
#include<string.h>
int val=0;
struct Ret 
{
    int exitno;
    int exittime;
    //...
};
void* Routine(void* avgs)
{
    int cnt=1;
    while(1)
    {
        printf("I am %s... val:%d\n",(char*)avgs,val);
        sleep(1);
        cnt++;
        if(cnt==3)
        {
            struct Ret* p=(struct Ret*)malloc(sizeof(struct Ret));
            p->exitno=0;
            p->exittime=6666;
            pthread_exit((void*)p);
            //pthread_cancel(pthread_self());
        }    
    }

}
int main()
{
    pthread_t tid1,tid2,tid3;
    pthread_create(&tid1,NULL,Routine,(void*)"pthread 1");
    pthread_create(&tid2,NULL,Routine,(void*)"pthread 2");
    pthread_create(&tid3,NULL,Routine,(void*)"pthread 3");
    int cnt=0;
    while(1)
    {
        printf("I am main pthread...val:%d\n",val++);
        sleep(1);
        cnt++;
        if(cnt==3)
            break;
    }
    printf("wait for pthread...\n");
    void* ret;
    pthread_join(tid1,&ret);
    printf("pthread id:%x exitno:%d exittime:%d\n",tid1,((struct Ret*)ret)->exitno,((struct Ret*)ret)->exittime);
    pthread_join(tid2,&ret);
    printf("pthread id:%x exitno:%d exittime:%d\n",tid2,((struct Ret*)ret)->exitno,((struct Ret*)ret)->exittime);
    pthread_join(tid3,&ret);
    printf("pthread id:%x exitno:%d exittime:%d\n",tid3,((struct Ret*)ret)->exitno,((struct Ret*)ret)->exittime);
    return 0;
}
  • 效果:
image-20220330232535739

6、线程分离

  • 概念:
  • pthread_detach函数原型:
int pthread_detach(pthread_t thread);
  • 注意:
  • 示例:
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
void* Routine (void* arg)
{
    pthread_detach(pthread_self());
    printf("%s detach success!\n");
    int cnt=0;
    while(cnt<5)
    {
        cnt++;
        printf("%s running...\n",(char*)arg);
        sleep(1);
    }
    printf("%s return...\n");
    return NULL;
}
int main()
{
    pthread_t tid;
    pthread_create(&tid,NULL,Routine,(void*)"thread");
    
    sleep(2);//等待线程分离

    void* ret;
    if(pthread_join(tid,&ret)==0)
        printf("thread join success! ret:%d\n",(int*)ret);
    else 
        printf("thread join fail... ret:%d\n",(int*)ret);
    return 0;
}
  • 效果:
image-20220331221532746
举报

相关推荐

0 条评论