多线程2——线程函数(linux)

1.线程创建函数 pthread_create

函数原型:

#include <pthread.h>
 
int pthread_create (pthread_t *__restrict __newthread,
			   const pthread_attr_t *__restrict __attr,
			   void *(*__start_routine) (void *),
			   void *__restrict __arg)

函数个参数含义如下:

  • __newthread : 该参数是一个指针,当线程创建成功时,用来返回创建的线程ID。
  • __attr : 该参数用于指定线程的属性,NULL表示使用默认属性。
  • __start_routine : 该参数是一个函数指针,指向线程创建后要调用的函数。这个被线程调用的函数也称为线程函数。
  • __arg :该参数指向传递给线程函数的参数。

注意:线程创建成功时,pthread_create函数返回0,若不为0,则说明线程创建失败。

线程创建代码示例

(1)不传递参数

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

int * thread(void *arg)
{
    pthread_t newthid;

    newthid = pthread_self();
    printf("this is a new thread, thread ID = %u\n", (unsigned int)newthid);

    return NULL;
}

int main(int argc, char **argv)
{
    pthread_t thid;

    printf("main thread, ID is %u\n", (unsigned int)pthread_self());

    if (pthread_create(&thid, NULL, (void *)thread, NULL) != 0) {
        printf("thread creation failed\n");
        exit(1);
    }

     sleep(1);  // 休眠1秒
    
    // pthread_exit作用
    // 1.显式地退出一个线程
    // 2.如果主线程在其创建的子线程之前结束,使用pthread_exit,进程不会结束,
    //    也意味着子线程可以继续执行;如果不使用pthread_exit,进程会结束
    //    子线程会被迫终止。
    // 3.该函数是在线程完成工作后无需继续存在时被调用,也意味着其后面的语句不被执行。
    pthread_exit(NULL);

    // 该语句位于pthread_exit后,不会被执行!
    printf("main end...");

    return 0;
}

编译并运行程序
baohua@node1:~$ gcc createthread.c -lpthread -o main
baohua@node1:~$ ./main
main thread, ID is 2957645568
this is a new thread, thread ID = 2949265152

(2)只有一个参数

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

void * thread(void *arg)
{
    pthread_t newthid;

    newthid = pthread_self();
    printf("this is a new thread, thread ID = %u\n", (unsigned int)newthid);

    // 获取父线程创建子线程时传递的参数
    int index = *((int *)arg);
    printf("the value of index is: %d\n", index);

    return NULL;
}

int main(int argc, char **argv)
{
    pthread_t thid;

    printf("main thread, ID is %u\n", (unsigned int)pthread_self());

    int index = 1;

    if (pthread_create(&thid, NULL, thread, (void *)&index) != 0) {
        printf("thread creation failed\n");
        exit(1);
    }

    // pthread_exit作用
    // 1.显式地退出一个线程
    // 2.如果主线程在其创建的子线程之前结束,使用pthread_exit,进程不会结束,
    //    也意味着子线程可以继续执行;如果不使用pthread_exit,进程会结束
    //    子线程会被迫终止。
    // 3.该函数是在线程完成工作后无需继续存在时被调用,也意味着其后面的语句不被执行。
    pthread_exit(NULL);

    // 该语句位于pthread_exit后,不会被执行!
    printf("main end...");

    return 0;
}

编译并运行程序
baohua@node1:~$ gcc createthread.c -lpthread -o main
baohua@node1:~$ ./main
main thread, ID is 1917601536
this is a new thread, thread ID = 1909221120
the value of index is: 1

(3)多个参数

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

struct thread_data
{
    int thread_id;
    char *message;
};

void *thread(void *arg)
{
    pthread_t newthid;

    newthid = pthread_self();
    printf("this is a new thread, thread ID = %u\n", (unsigned int)newthid);

    // 获取父线程创建子线程时传递的参数
    struct thread_data *my_data;
    my_data = (struct thread_data *)arg;
    printf("Thread ID: %d\n", my_data->thread_id);
    printf("Message: %s\n", my_data->message);

    return NULL;
}

int main(int argc, char **argv)
{
    pthread_t thid;

    printf("main thread, ID is %u\n", (unsigned int)pthread_self());

  // 借助结构体传参
    struct thread_data td;
    td.thread_id = 1;
    td.message = "This is message";

    if (pthread_create(&thid, NULL, thread, (void *)&td) != 0)
    {
        printf("thread creation failed\n");
        exit(1);
    }

    // pthread_exit作用
    // 1.显式地退出一个线程
    // 2.如果主线程在其创建的子线程之前结束,使用pthread_exit,进程不会结束,
    //    也意味着子线程可以继续执行;如果不使用pthread_exit,进程会结束
    //    子线程会被迫终止。
    // 3.该函数是在线程完成工作后无需继续存在时被调用,也意味着其后面的语句不被执行。
    pthread_exit(NULL);

    // 该语句位于pthread_exit后,不会被执行!
    printf("main end...");

    return 0;
}

编译并运行程序
baohua@node1:~$ gcc createthread.c -lpthread -o main
baohua@node1:~$ ./main
main thread, ID is 224532224
this is a new thread, thread ID = 216151808
Thread ID: 1
Message: This is message

2.线程终止

Linux下有三种方法使线程终止(不终止进程):

  • 线程函数执行到尾部,或使用return从线程函数返回
  • 线程可以被同一进程中的其他线程取消
  • 通过pthread_exit函数使线程退出

注意:在任何线程中调用exit函数,都会终止进程,进而导致所有线程终止。

线程终止最重要的问题是释放临界资源

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晴光

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值