linux:进程ID与线程ID&线程之间共享同一个虚拟地址空间

获得线程ID(此ID是内核级ID)

#include<sys/syscall.h>
pid_t tid;
tid=syscall(SYS_gettid);

示例

代码:

#include<stdio.h>
#include<sys/syscall.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>//线程相关函数的头文件
void*ThreadEntry(void*arg)
{
    (void)arg;
    pid_t ID=syscall(SYS_gettid);//获得当前线程的ID(内核级的ID)
    while(1)
    {
        printf("I am thread,用户态ID:%1x 所属进程ID: %d 内核级线程ID: %d \n",pthread_self(),getpid(),ID);
        sleep(1);
    }
}
int main()
{
    int ret=0;
    pid_t ID=syscall(SYS_gettid);//获得当前线程的ID(内核级的ID)
    pthread_t tid;
    ret=pthread_create(&tid,NULL,ThreadEntry,NULL);
    if(ret!=0)
    { 
        perror("pthread_create");
        exit(1);
    }
    while(1)
    {
        printf("I am main,用户态ID:%1x 所属进程ID: %d 内核级线程ID: %d \n",pthread_self(),getpid(),ID);
        sleep(1);
    }
    return 0;
}

运行结果:
这里写图片描述

每个线程会有两个ID,一个是用户态,另一个是内核级,内核级的ID是
区分线程唯一的标识符,而用户态ID是让我们用户来进行区分线程的,长
得像一个地址,当然本质上就是一个进程地址空间上的一个地址

线程组ID总是和主线程的线程组ID一致i,无论是主线程直接创建线程,还是
创建出来的线程再次创建线程

进程中有父进程的概念,而在线程中,在一个线程组里面,所有的线程都是对等的关系

线程之间是共享同一个虚拟地址空间的,共享以下:

1.全局变量
2.在堆上开辟的内存
3.在栈上开辟的内存

示例

1.共享全局变量
代码:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
int g_count=100;
void*ThreadEntry(void*arg)
{
    (void)arg;
    g_count=200;//在此线程中把g_count修改为200
    printf("I am thread\n");
    sleep(1);
}
int main()
{
    pthread_t tid;
    pthread_create(&tid,NULL,ThreadEntry,NULL);
    sleep(1);
    printf("g_count=%d\n",g_count);
    return 0;
}

运行结果:
这里写图片描述
在一个线程中修改了全局变量,那其他线程也会收到此变量的改变

2.在堆上开辟内存,共享同一个堆
(1)
代码:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
void*ThreadEntry(void*arg)
{
    int*ptr=(int*)arg;
    while(1)
    {
        printf("I am thread,thread ptr is %d......\n",*ptr);
        sleep(1);
    }
}
int main()
{
    int*ptr=(int*)malloc(sizeof(int));
    *ptr=10;
    pthread_t tid;
    pthread_create(&tid,NULL,ThreadEntry,ptr);
    while(1)
    {
        printf("I am main,main ptr is %d\n",*ptr);
        //ptr是传给线程启动函数的参数
        sleep(1);
    }
    free(ptr);
    return 0;
}

运行结果:
这里写图片描述
结果解析:
我们是在主线程(main函数)中从堆上开辟了一块内存,在另一个线程中输出内存中的值,得到了和主线程一样的结果,故线程之间共享同一块虚拟地址空间

(2)
代码:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
void*ThreadEntry(void*arg)
{
    int*ptr=(int*)arg;
    int n=0;
    *ptr=100;
    while(1)
    {
        if(n++>3)
            pthread_exit(NULL);//如果n>3,那此线程就退出
        printf("I am thread,thread p  is %d......\n",*ptr);
        sleep(1);
    }
}
int main()
{
    int count=9999;
    int *ptr=&count;
    pthread_t tid;
    pthread_create(&tid,NULL,ThreadEntry,(void*)ptr);
    printf("mian ptr=%d\n",*ptr);
    while(1)
    {
        pthread_join(tid,NULL);//等待新线程执行结束,才会执行自己
        printf("I am main,main ptr is %d\n",*ptr);
        sleep(1);
    }
    free(ptr);
    return 0;
}

运行结果:
这里写图片描述
结果解析:
在主线程中开辟了一块内存,并给此内存赋值,输出此值—>9999,创建新线程,并在新线程中修改在主线程开辟的那块内存的内容,主线程等待(pthread_join)新线程结束,再去执行自己,此时输出的ptr和新线程中的是一样的结果,故线程之间共享在堆上的空间

3.在栈上开辟内存,共享同一个栈
代码:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
void*ThreadEntry(void*arg)
{
    int*ptr=(int*)arg;
    while(1)
    {
        printf("I am thread,thread ptr is %d......\n",*ptr);
        sleep(1);
    }
}
int main()
{
    int count=9999;
    int *ptr=&count;
    pthread_t tid;
    pthread_create(&tid,NULL,ThreadEntry,ptr);
    //ptr是传给线程启动函数的参数
    while(1)
    {
        printf("I am main,main ptr is %d\n",*ptr);
        sleep(1);
    }
    free(ptr);
    return 0;
}

运行结果:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值