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

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

#include
pid_t tid;
tid=syscall(SYS_gettid);

示例

代码:

#include
#include
#include
#include
#include//线程相关函数的头文件
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;
}

运行结果:
linux:进程ID与线程ID&线程之间共享同一个虚拟地址空间_第1张图片

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

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

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

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

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

示例

1.共享全局变量
代码:

#include
#include
#include
#include
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;
}

运行结果:
linux:进程ID与线程ID&线程之间共享同一个虚拟地址空间_第2张图片
在一个线程中修改了全局变量,那其他线程也会收到此变量的改变

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

#include
#include
#include
#include
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;
}

运行结果:
linux:进程ID与线程ID&线程之间共享同一个虚拟地址空间_第3张图片
结果解析:
我们是在主线程(main函数)中从堆上开辟了一块内存,在另一个线程中输出内存中的值,得到了和主线程一样的结果,故线程之间共享同一块虚拟地址空间

(2)
代码:

#include
#include
#include
#include
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;
}

运行结果:
linux:进程ID与线程ID&线程之间共享同一个虚拟地址空间_第4张图片
结果解析:
在主线程中开辟了一块内存,并给此内存赋值,输出此值—>9999,创建新线程,并在新线程中修改在主线程开辟的那块内存的内容,主线程等待(pthread_join)新线程结束,再去执行自己,此时输出的ptr和新线程中的是一样的结果,故线程之间共享在堆上的空间

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

#include
#include
#include
#include
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;
}

运行结果:
linux:进程ID与线程ID&线程之间共享同一个虚拟地址空间_第5张图片

你可能感兴趣的:(linux)