初探线程01

1.线程的概念

①线程就是一个正在运行的程序
②是main线程在运行,不是主线程,没有主次之分,线程之间是平等的关系
③多个线程共享内存,在同一块内存空间内
④他们之间的通讯会很简单,他们打开的文件描述符都一模一样的,或者一个全局变量等等
⑤从并发角度来看, 线程比进程简单,线程是先标准化,才被实现出来
⑥POSIX线程是一个标准 pthread_t 类型
⑦CPU的调度是以线程为单位的
⑧Compile and link with -pthread

2.

你的会话是一个容器,用来容纳进程组,你的进程组是一个容器,用来容纳进程,你的进程是一个容器,用来容纳线程

3.pthread_equal

比较两个线程是否相等 各家对pthread_t这种类型的实现不同


NAME
       pthread_equal - compare thread IDs

SYNOPSIS
       #include <pthread.h>

       int pthread_equal(pthread_t t1, pthread_t t2);

       Compile and link with -pthread.

DESCRIPTION
       The pthread_equal() function compares two thread identifiers.

4.pthread_self

返回自己的线程id

NAME
       pthread_self - obtain ID of the calling thread

SYNOPSIS
       #include <pthread.h>

       pthread_t pthread_self(void);

       Compile and link with -pthread.

5.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);

on error, it returns an  error  number

第一个参数是回填的线程id
第二个参数是创建线程的属性,NULL 可以解决80%的问题
第三个参数是一个函数指针(我们前面提到 一个线程就是一个跑的函数 )
第四个参数是函数的参数
void * 作为参数 可以传递任何想传递的参数,可以封装成任意的结构体,传过去一个地址就ok
不设置errno

6.一个demo

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


void * Fun(void *p )
{
        puts("Thread Working!");

        return NULL;
}

int main()
{
        pthread_t tid;
        int err;

        puts("Begin");

        err = pthread_create(&tid, NULL, Fun, NULL);
        if(err)
        {
                fprintf(stderr, "pthCreate %s\n", strerror(err));
                exit(1);
        }


        puts("End");



        return 0;
}

在这里插入图片描述
感到很奇怪,为什么线程没有被执行呢?
原因是因为exit 八种进程终止的方式!
进程已经被杀死了
最简单的 你加一个sleep
在这里插入图片描述

7.线程的终止

①线程简单的从启动例程退出,返回值就是他的退出码
②线程调用pthread_exit();
③线程被同一进程中的其他线程取消

8.pthread_exit

NAME
       pthread_exit - terminate calling thread

SYNOPSIS
       #include <pthread.h>

       void pthread_exit(void *retval);
void * Fun(void *p )
{
        puts("Thread Working!");

        //return NULL;
        
        pthread_exit(NULL);
}

9.pthread_join

用来等待一个线程的结束,并进行资源的回收

NAME
       pthread_join - join with a terminated thread

SYNOPSIS
       #include <pthread.h>

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

相当于wait,但是wait收尸 收回来的是谁不重要
void * * retval收尸的线程返回的状态

int main()
{
        pthread_t tid;
        int err;

        puts("Begin");

        err = pthread_create(&tid, NULL, Fun, NULL);
        if(err)
        {
                fprintf(stderr, "pthCreate %s\n", strerror(err));
                exit(1);
        }

        pthread_join(tid, NULL);

        puts("End");


        return 0;
}

在这里插入图片描述

10栈的清理

在进程中我们使用钩子函数,当程序正常退出的时候,来执行我们希望的一些操作,线程中也有,只不过取钩子的过程,必须自己来做


- push and pop thread cancellation clean-up handlers

SYNOPSIS
       #include <pthread.h>

       void pthread_cleanup_push(void (*routine)(void *),
                                 void *arg);   
       void pthread_cleanup_pop(int execute);

由于是宏实现的,所以二者必须成对出现

11.一个demo


void CleanupFun(void *pStr)
{
        puts(pStr);
}



void * Fun(void *p )
{
        puts("Thread Working!");

        pthread_cleanup_push(CleanupFun, "Hello1");
        pthread_cleanup_push(CleanupFun, "Hello2");
        pthread_cleanup_push(CleanupFun, "Hello3");

        puts("push over");

        pthread_cleanup_pop(1);
        pthread_cleanup_pop(1);
        pthread_cleanup_pop(1);

        pthread_exit(NULL);
}

int main()
{
        pthread_t tid;
        int err;

        puts("Begin");

        err = pthread_create(&tid, NULL, Fun, NULL);
        if(err)
        {
                fprintf(stderr, "pthCreate %s\n", strerror(err));
                exit(1);
        }

        pthread_join(tid, NULL);

        puts("End");


        exit(0);
}

在这里插入图片描述

void * Fun(void *p )
{
        puts("Thread Working!");

        pthread_cleanup_push(CleanupFun, "Hello1");
        pthread_cleanup_push(CleanupFun, "Hello2");
        pthread_cleanup_push(CleanupFun, "Hello3");

        puts("push over");

		pthread_exit(NULL);
        pthread_cleanup_pop(0);
        pthread_cleanup_pop(0);
        pthread_cleanup_pop(0);

        
}

我把线程退出放到 pop之前,并且传参是0,但是还是被调用了,由于执行不到后面,所以都认为传参是1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值