LInux的Posix的线程控制

一,线程控制图

主线程<——>|工作队列 |<—-> 工作1 <—>工作2 <—>工作3
线程1<——> |工作队列 |<—-> 工作1 <—>工作2 <—>工作3
线程2<——>|工作队列 |<—-> 工作1 <—>工作2 <—>工作3
线程3<——>|工作队列 |<—-> 工作1 <—>工作2 <—>工作3

二,线程的标识符

  与进程标识符类似,每一个线程都有一个在进程中唯一的线程标识符(线程ID),其用数据类型 pthread_t 来表示的,该数据类型在Linux中其实就是一个无符号长整型数据。

LInux提供了两个函数用于对线程标识符,其标准调用格式说明如下:
#include <pthread.h>
pthread_t pthread_self(void);
pthread_self函数用于获取线程自身的线程标识符,其返回值是线程自身的线程标识符。
pthread_equal函数用于比较两个线程标识符,其标准调用格式说明如下:
#include <pthread.h>
int pthread_equal(pthread_tid, pthread_t tid2);

三,线程控制的相关函数

使用gcc编译多线程程序是, 必须与pthread函数库链接,在终端下编译使用下列 gcc -lpthread

1,pthread_create函数

文档说明


NAME
       pthread_create - create a new thread

SYNOPSIS
       #include <pthread.h>

       int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                          void *(*start_routine) (void *), void *arg);

       Compile and link with -pthread.

DESCRIPTION
       The  pthread_create()  function  starts  a  new  thread  in the calling
       process.  The new thread starts execution by invoking  start_routine();
       arg is passed as the sole argument of start_routine().

       The new thread terminates in one of the following ways:

       * It  calls  pthread_exit(3),  specifying  an exit status value that is
         available  to  another  thread  in  the  same  process   that   calls
         pthread_join(3).

一个例子

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

pthread_t ntid; //线程id

//打印标识符的函数
void printds(const char *s)
{
    pid_t pid; //进程标识符
    pthread_t tid;  //线程标识符

    pid = getpid(); // 获取进程标识符id
    //获取线程标识符的id
    tid = pthread_self();  


    printf("%s pid, %u tid %u (0x%x)\n", s, (unsigned int)pid, (unsigned int)tid, (unsigned int)tid);  //打印进程和线程id
}

//线程中开始运行的函数
void *thr_fn(void *arg)
{
    printds("new thread:");
    return ((void*)0);
}

int main(void)
{
    int err;
    err = pthread_create(&ntid, NULL, thr_fn, NULL);  //创建一个线程

    // 如果出错误打印财务标号
    if (err != 0)
    {
        printf("can't create thread %s\n", strerror(err));
    }

    //打印主线程号
    printds("main thread:");

    sleep(1);
    exit(0);
    return 0;
}

pthread_create线程效果图

可以看到标识符为7738的进程创建了两个标识符分别为 2274588416和2266298112 的线程。

2,pthread_exit函数
进程可以调用exit系列函数退出当前进程, 线程也可以通过如下3种方式退出, 子啊不终止整个进程的情况下停止线程的控制流
1,线程只是从启动列程种返回,返回值是线程的退出码。
2,线程可以被同一个进程中的其他进程终止。
3,线程调用pthread_exit函数退出
Linux内核提供pthread_exit函数用于主动退出线程, 其在LInux函数库种原型是:

NAME
       pthread_exit - terminate calling thread

SYNOPSIS
       #include <pthread.h>

       void pthread_exit(void *retval);

       Compile and link with -pthread.

DESCRIPTION
       The pthread_exit() function terminates the calling thread and returns a
       value via retval that (if the  thread  is  joinable)  is  available  to
       another thread in the same process that calls pthread_join(3).

       Any  clean-up handlers established by pthread_cleanup_push(3) that have
       not yet been popped, are popped (in the reverse of the order  in  which
       they  were pushed) and executed.  If the thread has any thread-specific
       data, then, after the clean-up handlers have been executed, the  corre‐
       sponding destructor functions are called, in an unspecified order.

3,pthread_join函数 我的理解就是没有pthread_join函数就执行pthread_create函数
如果当一个线程已经执行完成之后, 可以被其他的线程了阻塞挂起,过后等待指定的线程调用pthread_exit,以从启动列程中返回或被取消,LInux内核可以调用pthread_join函数来完成对线程阻塞,其在LInux函数库中的原型是:

NAME
       pthread_join - join with a terminated thread

SYNOPSIS
       #include <pthread.h>

       int pthread_join(pthread_t thread, void **retval);

       Compile and link with -pthread.

DESCRIPTION
       The pthread_join() function waits for the thread specified by thread to
       terminate.  If that thread has already terminated, then  pthread_join()
       returns immediately.  The thread specified by thread must be joinable.

       If  retval  is  not NULL, then pthread_join() copies the exit status of
       the target thread (i.e., the value that the target thread  supplied  to
       pthread_exit(3))  into the location pointed to by *retval.  If the tar‐
       get thread was canceled, then PTHREAD_CANCELED is placed in *retval.

       If multiple threads simultaneously try to join with  the  same  thread,

返回:如果调用成功,函数返回0, 反之返回一个非0值

例子:

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

void print_msg(char *ptr);


int main(void)
{
    pthread_t thread1, thread2;
    int i, j;
    void *retval;

    char *msg1 = "This is the frist thread\n";
    char *msg2 = "This is the second thread\n";


    pthread_create(&thread1, NULL, (void *)(&print_msg),(void *)msg1);

    pthread_create(&thread2, NULL, (void *)(&print_msg), (void *)msg2);  //创建两个线程

    pthread_join(thread1, &retval);
    pthread_join(thread2, &retval);
    return 0;
}

//打印信息函数, 线程从这个函数开始执行
void print_msg(char *ptr)
{
    int i;
    for( i = 0; i < 10; i++)
    {
        //连续输出10个字符串
        printf("%s\n", ptr); 
    }
}

运行效果图
效果图

4,pthread_cancel函数

pthread_cancel函数

返回:如果操作成功返回0,失败返回对应错误码

5,pthread_cleanup_push和pthread_cleanup_pop函数
当调用pthread_cancel函数取消了一个线程之后,需要调用相应的函数对进程退出之后的环境继续清理,
这里写图片描述

1,调用pthread_exit函数的时候
2,响应取消请求的时候
3,用非execute参数调用pthread_cleanup_pop的时候

6,pthread_detach函数

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值