← 返回首页
Linux高级程序设计(七十)
发表时间:2021-12-22 23:13:03
创建线程

就像每一个进程都有一个唯一的进程号一样,线程也有一个唯一的线程号,但是这个线程号仅仅在其所在的进程环境中有效。

进程号用pid_t表示一个非负整数,线程号不是系统唯一, 而是进程环境中唯一有效。线程的句柄是pthread_t类型, 该类型不能作为整数处理, 而是一个结构。

1.线程创建

使用pthread_create()函数来创建线程。

#include <pthread.h>

int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(start_rtn)(void), void *restrict arg);

参数: - tidp: 指向新创建线程ID的变量, 作为函数的输出。 - attr: 用于定制各种不同的线程属性, NULL为默认属性(见下)。 - start_rtn: 函数指针, 为线程开始执行的函数名.该函数可以返回一个void *类型的返回值,而这个返回值也可以是其他类型,并由 pthread_join()获取。 - arg: 函数的唯一无类型(void)指针参数, 如要传多个参数, 可以用结构封装。

返回值: - 成功则返回0, 否则返回错误编号。

注意:线程依赖于进程,如果创建线程的进程结束了,那么线程也就结束了。

实例:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

void *thr_fn(void *arg)
{
    printf("new thread is running...\n");
}

int main(int argc, char const *argv[])
{
    printf("main thread is running....\n");
    pthread_t thread;

    if (pthread_create(&thread, NULL, thr_fn, NULL) != 0)
    {
        perror("error to pthread_create:");
        exit(-1);
    }

    while(1); //保证主线程不结束...

    return 0;
}

测试运行:

注意:多线程程序的编译必须添加-lpthread 参数。

[root@iz2zefozq9h39txdb8s7npz shelldemo]# gcc test_thcreate.c -lpthread
[root@iz2zefozq9h39txdb8s7npz shelldemo]# ./a.out
main thread is running....
new thread is running...

^Z
[1]+  Stopped                 ./a.out

2.线程的调度

多线程执行顺序是不确定的,每个线程轮流使用CPU资源,时间片到后线程切换。

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

void *thr_fn1(void *arg)
{
    printf("new thread1 is running...\n");
    sleep(1);
    printf("************thread1************\n");
}

void *thr_fn2(void *arg)
{
    printf("new thread2 is running...\n");
    sleep(1);
    printf("************thread2************\n");
}

int main(int argc, char const *argv[])
{
    printf("main thread is running....\n");
    pthread_t thread;

    if (pthread_create(&thread, NULL, thr_fn1, NULL) != 0)
    {
        perror("error to pthread_create:");
        exit(-1);
    }

    if (pthread_create(&thread, NULL, thr_fn2, NULL) != 0)
    {
        perror("error to pthread_create:");
        exit(-1);
    }

    while(1); //保证主线程不结束...

    return 0;
}

运行结果:

[root@iz2zefozq9h39txdb8s7npz shelldemo]# ./a.out
main thread is running....
new thread2 is running...
new thread1 is running...
************thread1************
************thread2************
^Z

3.线程传参

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

int num = 100;
void *thr_fn1(void *arg)
{
    printf("new thread1 is running...\n");
    num++; //修改全局变量num;
    int n = *(int*)arg;
    printf("in thread1 counter=%d\n",n);
    (*(int*)arg)++;
    //*(int*)arg=777;
    sleep(1);
    printf("************thread1************\n");
}

void *thr_fn2(void *arg)
{
    sleep(1);
    printf("new thread2 is running...\n");
    printf("num=%d\n",num);
    int n = *(int*)arg;
    printf("in thread2 counter=%d\n",n);
    printf("************thread2************\n");
}

int main(int argc, char const *argv[])
{
    printf("main thread is running....\n");
    pthread_t thread;

    int counter=666;

    //线程传参
    if (pthread_create(&thread, NULL, thr_fn1, (void *)&counter) != 0)
    {
        perror("error to pthread_create:");
        exit(-1);
    }

    if (pthread_create(&thread, NULL, thr_fn2, (void *)&counter) != 0)
    {
        perror("error to pthread_create:");
        exit(-1);
    }

    while(1); //保证主线程不结束...

    return 0;
}

运行结果:

[root@iz2zefozq9h39txdb8s7npz shelldemo]# ./a.out
main thread is running....
new thread1 is running...
in thread1 counter=666
new thread2 is running...
num=101
in thread2 counter=667
************thread2************
************thread1************
^Z