进程原语 线程原语 描述
fork pthread_create 创建新的控制流
exit pthread_exit 从现有的控制流中退出
waitpid pthread_join 从控制流中得到退出状态
atexit pthread_cancel_push 注册在退出控制流时调用的函数
getpid pthread_self 获取控制流的ID
abort pthread_cancel 请深圳市控制流的非正常退出

pthread_create

int pthread_create(pthread_t *thread, pthread_addr_t *arr,void* (*start_routine)(void *), void *arg);

  • thread    :用于返回创建的线程的ID
  • arr         : 用于指定的被创建的线程的属性,上面的函数中使用NULL,表示使用默认的属性
  • start_routine      : 这是一个函数指针,指向线程被创建后要调用的函数
  • arg        : 用于给线程传递参数,在本例中没有传递参数,所以使用了NULL
 
线程创建时并不能保证哪个线程会先运行:是新创建的线程还是调用线程。新创建的线程可以访问进程的地址空间,
并且继承调用线程的浮点环境和信号屏蔽字,但是该线程的未决信号集被消除。
 
单个线程可以通过三种方式退出,在不终止整个进程的情况下停止它的控制流。
(1)线程只是从启动全程中返回,返回值是线程的退出码。
(2)线程可以被同一进程中的其他线程取消
(3)线程调用pthread_exit
 
 
void pthread_exit(void *rval_ptr)
rval_ptr是一个无类型指针,与传给启动例程的单个参数类似。进程中的其他线程可以通过调用pthread_join函数访问到这个指针。
 
int pthread_join(pthread_t thread,void **rval_ptr);
成功返回0,失败返回错误编号
调用线程将一直阻塞,直到指定的线程调用pthread_exit,从启动例程中返回或者被取消。
如果线程只是从它的启动例程返回,rval_ptr将包含返回码。如果线程被取消,由rval_ptr指定的内存单元被置为PTHREAH_CANCELED.
可以通过调用pthread_join自动把线程置于分离状态,这样资源就可以恢复。如果线程已经处于分离状态,pthread_join调用就会失败,返回EINVAL.
如果对线程的返回值并不感兴趣,可以把rval_ptr置为NULL。在这种情况下,调用pthread_join函数将等待指定的线程停止,但并不获取线程的终止状态。
 
在 调用线程的栈上分配了该结构,那么其他的线程在使用这个结构进内存可能已经改变了。又如,线程在自己的栈上分配了一个结构然后把指向这个结构的指针传给 pthread_exit,那么当调用pthread_join的线程试图使用该结构时,这个栈有可能已经被撤消,这块内存也已另作他用。
例如:#include <stdlib.h>
 
void pthread_cleanup_push(void (*rtn)(void *),void *arg);
void pthread_cleanup_pop(int execute);
当线程执行以下动作时调用清理函数,调用参数为arg,清理函数rtn的调用顺序是由pthread_cleanup_push函数来安排的。
1.调用pthread_exit时。2.响应取消请求时。3.用非零execute参数调用pthread_cleanup_pop时。
如果execute参数置为0,清理函数将不被调用。无论哪种情况,pthread_cleanup_pop都将删除上次pthread_clean_push调用建立的清理处理程序。
实例:
 #include <stdlib.h>
#include <stdio.h>
#include <pthread.h> void cleanup(void *arg)
{
printf("cleanup: %s\n", (char *)arg);
} void *thr_fn1(void *arg)
{
printf("thread 1 start\n");
pthread_cleanup_push(cleanup, "thread 1 first handler");
pthread_cleanup_push(cleanup, "thread 1 second handler");
printf("thread 1 push complete\n");
if (arg)
return((void *));
// pthread_exit((void *)2); pthread_cleanup_pop();
pthread_cleanup_pop();
// return((void *)1);
pthread_exit((void *)); } void *thr_fn2(void *arg)
{
printf("thread 2 start\n");
pthread_cleanup_push(cleanup, "thread 2 first handler");
pthread_cleanup_push(cleanup, "thread 2 second handler");
printf("thread 2 push complete\n");
if (arg)
pthread_exit((void *));
pthread_cleanup_pop();
pthread_cleanup_pop();
pthread_exit((void *));
} int main(void)
{
int err;
pthread_t tid1, tid2;
void *tret; err = pthread_create(&tid1, NULL, thr_fn1, (void *));
if (err != )
printf("can't create thread 1: %c\n", strerror(err));
err = pthread_create(&tid2, NULL, thr_fn2, (void *));
if (err != )
printf("can't create thread 2: %c\n", strerror(err));
err = pthread_join(tid1, &tret);
if (err != )
printf("can't join with thread 1: %c\n", strerror(err));
printf("thread 1 exit code %d\n", (int)tret);
err = pthread_join(tid2, &tret);
if (err != )
printf("can't join with thread 2: %c\n", strerror(err));
printf("thread 2 exit code %d\n", (int)tret);
exit();
}

linux c学习笔记----线程创建与终止的更多相关文章

  1. linux c学习笔记----进程创建(fork,wait,waitpid)

    1.pid_t fork(); (1)当一个进程调用了fork 以后,系统会创建一个子进程.这个子进程和父进程不同的地方只有他的进程ID 和父进程ID,其他的都是一样.就象符进程克隆(clone)自己 ...

  2. Java学习笔记-多线程-创建线程的方式

    创建线程 创建线程的方式: 继承java.lang.Thread 实现java.lang.Runnable接口 所有的线程对象都是Thead及其子类的实例 每个线程完成一定的任务,其实就是一段顺序执行 ...

  3. Java基础学习总结(88)——线程创建与终止、互斥、通信、本地变量

    线程创建与终止 线程创建 Thread类与 Runnable 接口的关系 public interface Runnable {         public abstract void run(); ...

  4. Linux系统学习笔记:文件I/O

    Linux支持C语言中的标准I/O函数,同时它还提供了一套SUS标准的I/O库函数.和标准I/O不同,UNIX的I/O函数是不带缓冲的,即每个读写都调用内核中的一个系统调用.本篇总结UNIX的I/O并 ...

  5. Linux内核学习笔记-2.进程管理

    原创文章,转载请注明:Linux内核学习笔记-2.进程管理) By Lucio.Yang 部分内容来自:Linux Kernel Development(Third Edition),Robert L ...

  6. Linux内核学习笔记二——进程

    Linux内核学习笔记二——进程   一 进程与线程 进程就是处于执行期的程序,包含了独立地址空间,多个执行线程等资源. 线程是进程中活动的对象,每个线程都拥有独立的程序计数器.进程栈和一组进程寄存器 ...

  7. 尚硅谷韩顺平Linux教程学习笔记

    目录 尚硅谷韩顺平Linux教程学习笔记 写在前面 虚拟机 Linux目录结构 远程登录Linux系统 vi和vim编辑器 关机.重启和用户登录注销 用户管理 实用指令 组管理和权限管理 定时任务调度 ...

  8. Linux内核学习笔记-1.简介和入门

    原创文章,转载请注明:Linux内核学习笔记-1.简介和入门 By Lucio.Yang 部分内容来自:Linux Kernel Development(Third Edition),Robert L ...

  9. linux kernel学习笔记-5内存管理_转

    void * kmalloc(size_t size, gfp_t gfp_mask); kmalloc()第一个参数是要分配的块的大小,第一个参数为分配标志,用于控制kmalloc()的行为. km ...

随机推荐

  1. [转]Python机器学习工具箱

    原文在这里  Python在科学计算领域,有两个重要的扩展模块:Numpy和Scipy.其中Numpy是一个用python实现的科学计算包.包括: 一个强大的N维数组对象Array: 比较成熟的(广播 ...

  2. Double-Array Trie 原理解析

     http://ansjsun.iteye.com/blog/702255     Trie树是搜索树的一种,它在本质上是一个确定的有限状态自动机,每个结点代表一个状态,根据输入变量的不同,进行状态转 ...

  3. Eclipse 文件太长,导致着色异常问题

    1. 把C/C++ ->Editor->Scalability, 对应红框中的数字调大.

  4. 利用OSG实现模拟飞机尾迹-粒子系统

    利用OSG实现模拟飞机尾迹-粒子系统 粒子系统简介:         粒子系统是用于不规则模糊物体建模及图像生成的一种方法.         粒子系统是一种过程模型,即利用各种计算过程生成模型各个体素 ...

  5. 自己定义View时,用到Paint Canvas的一些温故,简单的帧动画(动画一 ,&quot;掏粪男孩Gif&quot;顺便再提提onWindowFocusChanged)

    转载请注明出处:王亟亟的大牛之路 之前在绘画的过程中提到了静态的旋转啊,缩放啊,平移等一些效果.那么自己定义的View当然也有动态的效果也就是我们的Animation.经常使用的有三种 View An ...

  6. [Functional Programming] Using Last monoid with Maybe

    Imaging we have a deck of cards, eveytimes we need to pick one card from deck, the result we want to ...

  7. [Canvas]New Running Dog

    欲看效果请下载后用Chrome浏览器打开index.html观看,下载地址:https://files.cnblogs.com/files/xiandedanteng/51-NewRunningDog ...

  8. 从头认识java-15.7 Map(7)-TreeMap与LinkedHashMap

    这一章节我们来讨论一下Map两个比較经常使用的实现:TreeMap与LinkedHashMap. 1.TreeMap 特性:依照key来排序 package com.ray.ch14; import ...

  9. SHELL AWK 循环求和

    1.简单求和,文件如下: [linux@test /tmp]$ cat test 123.52 125.54 126.36 求和: [linux@test /tmp]$ awk '{sum += $1 ...

  10. k-means算法MATLAB和opencv代码

    上一篇博客写了k-means聚类算法和改进的k-means算法.这篇博客就贴出相应的MATLAB和C++代码. 下面是MATLAB代码,实现用k-means进行切割: %%%%%%%%%%%%%%%% ...