多线程之pthread_create创建线程

pthreads定义了一套C程序语言类型、函数、与常量。以pthread.h和一个线程库实现。

数据类型:

pthread_t:线程句柄

pthread_attr_t:线程属性

线程操作函数:

pthread_create():创建一个线程

pthread_exit():终止当前线程

pthread_cancel():中断另外一个线程的运行

pthread_join():阻塞当前的线程,直到另外一个线程运行结束

pthread_attr_init():初始化线程的属性

pthread_attr_setdetachstate():设置脱离状态的属性

pthread_attr_getdetachstate():获取脱离状态的属性

pthread_attr_destroy():删除线程的属性

pthread_kill():向线程发送一个信号

.....

创建线程:

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

*thread:线程id (指向线程标识符的指针)

*attr:线程属性(通常为空)

*start_rtn:线程要执行的函数(线程运行函数的起始地址)

*arg:start_rtn的参数

返回值为零才算成功,其它表示错误

编译时需要加上 -lpthread库

示例一:

#include <stdio.h>

#include <pthread.h>

void *pthread_1(void)      //线程1执行的函数

{

inti;

for(i=1; i < 5; i++){

printf("pthread1.\n");

sleep(1);

}

return (void *)0;

}

void *pthread_2(void)      //线程2执行的函数

{

inti;

for(i=1;i < 5; i++){

printf("pthread2.\n");

sleep(1);

}

return (void *)0;

}

int main(int argc, char argv[])

{

intret = 0;

pthread_tpthid1, pthid2;        //线程的id

ret= pthread_create(&pthid1,NULL, (void *)pthread_1, NULL);

if(ret)       // 非0则创建失败

{

perror("createthread 1 failed.\n");

return1;

}

ret= pthread_create(&pthid2, NULL, (void *)pthread_2, NULL);

if(ret)

{

perror("createthread 2 failed.\n");

return1;

}

pthread_join(pthid1,NULL);    //等待pthid1,否则不会等待,继续往下执行

pthread_join(pthid2,NULL);    //如无,遇到下面的return会结束进程

return0;

}

示例二:传递参数,初始化

/*

*pthread_init.c

*

* Created on: Jan 20, 2013

*     Author: linuxdba@qq.com

*/

#include <stdio.h>

#include <pthread.h>

void *create(void *arg)

{

int *num;

        num = (int*)arg;

printf("theinput number is: %d.\n", *num);

return(void *)0;

}

int main(int argc, char argv[])

{

intret;

intt;

printf("Inputone number:");

scanf("%d",&t);

int*attr = &t;

pthread_tpthid;

ret= pthread_create(&pthid, NULL, (void *)create, (void *)attr);

if(ret)

{

perror("createthread failed.\n");

return1;

}

pthread_join(pthid,NULL);

return0;

}

示例三:共享数据

/*

*pthread_share.c

*

* Created on: Jan 20, 2013

*     Author: linuxdba@qq.com

*/

#include <stdio.h>

#include <pthread.h>

static int i = 3;

void *pthread_1(void)

{

printf("thread1, i is: %d.\n", i);

return(void *)0;

}

void *pthread_2(void)

{

printf("thread2, i is: %d.\n", i);

return(void *)0;

}

int main(int argc, char argv[])

{

intret = 0;

inti = 5;

pthread_tpthid1, pthid2;

printf("mainthread, i is: %d.\n", i);

ret= pthread_create(&pthid1, NULL, (void *)pthread_1, NULL);

if(ret)

{

printf("createthread 1 failed.\n");

return1;

}

ret= pthread_create(&pthid2, NULL, (void *)pthread_2, NULL);

if(ret)

{

printf("createthread 2 failed.\n");

return1;

}

pthread_join(pthid1,NULL);

pthread_join(pthid2,NULL);

return0;

}

此段程序之中两个线程是对等的,不存在先后顺序;

i 为全局变量,main函数内部为局部的变量。

http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_create.3.html

http://baike.baidu.com/view/974776.htm

多线程设计之线程清理pthread_cleanup

线程清理:pthread_cleanup_push() &  pthread_cleanup_pop()

 

A cancellation clean-up handler is poppedfrom the stack and executed in

The following circumstances:(三种情况会执行线程清理)

1.        When a thread is canceled, allof the stacked clean-up handlers are popped and executed in the reverse of theorder in which they were pushed onto the stack. (线程取消)

2.        When a thread terminates bycallingpthread_exit(3),all clean-up handlers are executed as described in the preceding point.  (Clean-up handlers are not called if thethread terminates by performing a return from the thread start function.) (push与pop之间执行了pthread_exit)

3.        When a thread calls pthread_cleanup_pop()with a nonzero execute argument, the top-most clean-up handler is popped andexecuted.(pop内为非零参数)

 

示例代码:

/*

*pthread_push_pop.c

*

* Created on: Jan 21, 2013

*     Author: linuxdba@qq.com

*/

#include <stdio.h>

#include <pthread.h>

void *clean1(void *arg)

{

printf("clean1func: %s\n", arg);

return(void *)0;

}

void *clean2(void *arg)

{

printf("clean2func: %s\n", arg);

return(void *)0;

}

void *thread(void )

{

pthread_tthid;

thid= pthread_self();                //获取线程ID

printf("thethread is: %d.\n",thid);

printf("theprocess id is: %d.\n", getpid());     //进程ID

pthread_cleanup_push((void*)clean1,"first push");

pthread_cleanup_push((void*)clean2, "second push");

printf("Inthread.\n");

pthread_exit("threadexit.\n");       //退出线程,会执行push指定函数

/*return  NULL; */       //不会执行push指定函数

pthread_cleanup_pop(0);//为0,只有在异常退出时才会执行push指定的函数,pop第一个

pthread_cleanup_pop(1);//为非0,即便是正常,也会执行push指定的函数,pop第二个

returnNULL;

}

int main(int argc, char argv[])

{

intret = 0;

pthread_tpthid;

ret= pthread_create(&pthid, NULL,(void *)thread,NULL);

if(ret)

{

printf("createthread failed.\n");

return-1;

}

printf("theprocess is: %d.\n", getpid());         //获取进程ID

pthread_join(pthid,NULL);

}

运行结果:

the process is: 3893.

the thread is:1738999552.

the process id is: 3893.

In thread.

clean2 func: second push

clean1 func: first push

push与pop采用栈方式,先进后出,后进先出,所以clean2会在前面。

 

需要注意的几点:

1)        线程属于进程的,只有一个进程ID,一样的;

2)        push和pop是采用栈方式;

3)        pthread_cleanup_pop后面为0则执行push指定函数,非0则即便正常也执行

4)        push与pop之间代码若异常退出,包括pthread_exit,会进行相应的函数处理,但是若其间执行了return,则直接结束线程,不执行push指定函数。

参考文档:

http://man7.org/linux/man-pages/man3/pthread_cleanup_push.3.html

POSIX多线程之创建线程pthread_create && 线程清理pthread_cleanup的更多相关文章

  1. C++ Linux 多线程之创建、管理线程

    线程就是,在同一程序同一时间内同意运行不同函数的离散处理队列. 这使得一个长时间去进行某种特殊运算的函数在运行时不阻碍其它的函数变得十分重要. 线程实际上同意同一时候运行两种函数,而这两个函数不必相互 ...

  2. 7、Java并发性和多线程-如何创建并运行线程

    以下内容转自http://ifeve.com/creating-and-starting-java-threads/: Java线程类也是一个object类,它的实例都继承自java.lang.Thr ...

  3. Java多线程的创建(一)

    方法一:继承Thread类实现 1.创建一个类A,并继承Thread类 2.重写A的run()方法 3.创建A的实例对象b,即创建了线程对象 4.使用b调用start()方法:启动线程(会自动调用ru ...

  4. POSIX多线程—线程基本概念

    http://blog.csdn.net/livelylittlefish/article/details/7957007 作者:阿波链接:http://blog.csdn.net/livelylit ...

  5. iOS开发多线程篇—创建线程

    iOS开发多线程篇—创建线程 一.创建和启动线程简单说明 一个NSThread对象就代表一条线程 创建.启动线程 (1) NSThread *thread = [[NSThread alloc] in ...

  6. POSIX多线程——基本线程管理函数介绍

    POSIX基本的几个线程管理函数见下表: ------------------------------------------------------------------------------- ...

  7. posix多线程--线程取消

    1.三种取消状态Off                   禁用取消Deferred           推迟取消:在下一个取消点执行取消Asynchronous   异步取消:可以随时执行取消 in ...

  8. posix多线程--三种基本线程编程模型

    本文介绍了三种构建线程解决方案的方式. 一.流水线:每个线程执行同一种操作,并把操作结果传递给下一步骤的线程. 代码示例如下:终端输入一个int值,每个线程将该值加1,并将结果传给下一个线程. #in ...

  9. java多线程-概念&创建启动&中断&守护线程&优先级&线程状态(多线程编程之一)

    今天开始就来总结一下Java多线程的基础知识点,下面是本篇的主要内容(大部分知识点参考java核心技术卷1): 1.什么是线程以及多线程与进程的区别 2.多线程的创建与启动 3.中断线程和守护线程以及 ...

随机推荐

  1. 两款不错的js甘特图控件

    dhtmlx:https://docs.dhtmlx.com/ jQuery.Gantt:http://taitems.github.io/jQuery.Gantt/

  2. Redis禁用部分危险命令(keys/flushdb等)

    在redis.conf文件[SECURITY]区域配置: 1.禁用命令: rename-command KEYS "" rename-command FLUSHALL " ...

  3. 向net core 3.0进击——多平台项目发布与部署

    前言 在经历过好多折腾后,总算是把部署走通了一遍,之前只是简单创建个工程在linux下部署,后来一直将这件事搁置,直到最近刚好团队入手一个小服务器,很显然是linux的,那就没啥说的了,Come On ...

  4. 【转载】 tf.Print() (------------ tensorflow中的print函数)

    原文地址: https://blog.csdn.net/weixin_36670529/article/details/100191674 ------------------------------ ...

  5. shell比较浮点数

    1 t1="3123982193.090000000"; 2 t2="7872348342.003000000"; 3 if [ `expr $t2 \> ...

  6. CentOS7下安装Nexus私服及基础配置

    环境准备 VMware上安装CentOS7 XShell/Xftp NexusOSS-3.10 jdk1.8 安装 使用root用户登录,将安装包均放置在/usr/local文件夹下 使用Xshell ...

  7. 第一次使用markdown

    一级标题 二级标题 三家标题 四级标题 五级标题 六级标题 用两个空格来换行 斜体字 斜体字 加粗字体 加粗字体 斜体加粗字体 斜体加粗字体 无序列表用*或者+或者-: 第一箱 第二项 第三项 第四项 ...

  8. java js ur特殊格式处理 json 特殊格式处理

    url特殊格式处理: js中使用 encodeURIComponent() 编码对应的value $.ajax({ type: "post", url: "/tb_are ...

  9. Maven name=archetypeCatalog value=internal

    来源 https://www.cnblogs.com/del88/p/6286887.html IDEA根据maven archetype的本质,其实是执行mvn archetype:generate ...

  10. log4j Logger 使用简介

    项目结构: log4j.properties 内容: log4j.rootCategory=info,stdout log4j.appender.stdout=org.apache.log4j.Con ...