- 浏览: 1331015 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
chinaxy1:
...
ON DUPLICATE KEY UPDATE重复插入时更新 -
b_l_east:
不一定哦,就算大小相当,in 和 exists的性能也会很大差 ...
mysql查询语句in和exists二者的区别和性能影响 -
llp1990311:
[size=x-small][/size]
如何正确防御xss攻击 -
home198979:
q315506754 写道还是佩服写c的 用其它语言一样可以实 ...
玩转深度优先搜索算法 -
q315506754:
还是佩服写c的
玩转深度优先搜索算法
进程原语 | 线程原语 | 描述 |
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>
#include <stdio.h>
#include <pthread.h>
struct foo {
int a, b, c, d;
};
void printfoo(const char *s, const struct foo *fp)
{
printf("%s",s);
printf(" structure at 0x%x\n", (unsigned)fp);
printf(" foo.a = %d\n", fp->a);
printf(" foo.b = %d\n", fp->b);
printf(" foo.c = %d\n", fp->c);
printf(" foo.d = %d\n", fp->d);
}
void *thr_fn1(void *arg)
{
struct foo foo = {1, 2, 3, 4};
printfoo("thread 1:\n", &foo);
pthread_exit((void *)&foo);
}
void *thr_fn2(void *arg)
{
struct foo fao = { 2,2, 3, 4};
printf("thread 2: ID is %d\n", (unsigned int)pthread_self());
pthread_exit((void *)0);
}
int main(void)
{
int err;
pthread_t tid1, tid2;
struct foo *fp;
err = pthread_create(&tid1, NULL, thr_fn1, NULL);
if (err != 0)
printf("can't create thread 1: %d\n", strerror(err));
err = pthread_join(tid1, (void *)&fp);
if (err != 0)
printf("can't join with thread 1: %d\n", strerror(err));
sleep(1);
printf("parent starting second thread\n");
err = pthread_create(&tid2, NULL, thr_fn2, NULL);
if (err != 0)
printf("can't create thread 2: %d\n", strerror(err));
sleep(1);
printfoo("parent:\n", fp);
exit(0);
}
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 *)1);
// pthread_exit((void *)2);
pthread_cleanup_pop(0);
pthread_cleanup_pop(0);
// return((void *)1);
pthread_exit((void *)2);
}
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 *)2);
pthread_cleanup_pop(0);
pthread_cleanup_pop(0);
pthread_exit((void *)2);
}
int main(void)
{
int err;
pthread_t tid1, tid2;
void *tret;
err = pthread_create(&tid1, NULL, thr_fn1, (void *)1);
if (err != 0)
printf("can't create thread 1: %c\n", strerror(err));
err = pthread_create(&tid2, NULL, thr_fn2, (void *)1);
if (err != 0)
printf("can't create thread 2: %c\n", strerror(err));
err = pthread_join(tid1, &tret);
if (err != 0)
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 != 0)
printf("can't join with thread 2: %c\n", strerror(err));
printf("thread 2 exit code %d\n", (int)tret);
exit(0);
}
发表评论
-
【转载】如何用Linux的命令正确识别cpu的个数和核数
2013-08-20 11:40 1876如何在Linux下cpu的个数和核数呢?googel了一下 ... -
redis2.6.9源码学习---ziplist
2013-05-16 12:05 1748ziplist相比之前分析的z ... -
redis2.6.9源码学习---zipmap
2013-05-02 17:03 2213在看此文件源码之前,先看到此文件头部的英文注释,以下是本人 ... -
redis2.6.9源码学习---zipmap
2013-05-02 14:22 0<div class="iteye-blog- ... -
非阻塞connect编程
2013-04-08 17:08 1709非阻塞模式有3种用途 1.三次握手同时做其他的处理。co ... -
C库需要注意的函数
2013-03-08 16:50 2176本文转自:http://hub.opensolaris ... -
redis2.6.9源码学习---adlist
2013-02-07 16:27 1266源码adlist.c adlist.h,先来看看adlist ... -
redis2.6.9源码学习---dict
2013-02-07 11:59 1454redis的hashtable------dict.c ... -
redis2.6.9源码学习---Big_Endian&Little_Endian
2013-02-04 10:50 2719在阅读redis源码/src/endianconv.c时遇 ... -
linux c学习笔记----SCTP基础客户/服务编程(setsockopt,sctp_sendmsg等)
2013-01-15 17:53 19645在编程之前先了解一下sctp套接字选项 setsoc ... -
linux c学习笔记----UDP基础客户/服务编程(sendto,recvfrom)
2013-01-14 18:01 53682sendto(经socket传送数据) 相关函数 ... -
linux c学习笔记----select函数详解
2013-01-11 17:25 20232select系统调用是用来让我们的程序监视多个文件句柄(fil ... -
linux c学习笔记----TCP基础客户/服务编程(socket,bind等)
2013-01-10 17:29 28387socket(建立一个socket通信) 相关 ... -
linux c学习笔记----互斥锁属性
2013-01-05 18:37 11462互斥锁属性 使用互斥锁(互斥)可以使线程按顺序执行。通 ... -
linux c学习笔记----线程属性
2013-01-04 17:38 4544一.线程属性 线程具有属性,用pthre ... -
linux c学习笔记----线程同步
2012-12-28 17:49 29851.互斥量 互斥变量用pthead_mutex_t数据类 ... -
linux c学习笔记----共享内存(shmget,shmat,shmdt,shmctl)
2012-12-11 18:08 36657shmgetint shmget(key_t key, siz ... -
linux c学习笔记----消息队列(ftok,msgget,msgsnd,msgrcv,msgctl)
2012-12-07 17:46 33293ftok() #include <sys/t ... -
linux信号列表
2012-11-30 16:40 2766我们运行如下命令, ... -
linux c学习笔记----信号(sigaction,sigaddset,sigprocmask)
2012-11-30 16:23 15208sigaction(查询 ...
相关推荐
【linux学习笔记--17】POSIX IPC——消息队列.doc 【linux学习笔记--18】POSIX IPC——信号量.doc 【linux学习笔记--19】POSIX IPC——共享内存.doc 【linux学习笔记-10】Linux进程相关系统调用(三).doc 【linux...
【linux学习笔记-7】用户标识UID与有效用户标识EUID 【linux学习笔记-8】Linux进程相关系统调用(1) 【linux学习笔记-9】Linux进程相关系统调用(2) 【linux学习笔记-10】Linux进程相关系统调用(3) 【linux学习...
armlinux学习笔记--IIS音频驱动程序分析
ARM linux学习笔记--IIS音频驱动程序分析整理
Python学习笔记--皮大庆,非常适合零基础入门。对应英文版本《How to think like a computer scientist》
认真学习的人从国内某个培训机构上课时,记录的C语言学习笔记,其中包含所有的C语言基本语法,文章中对指针、字符操作有好多介绍,整理的很全面,并且有图示哦!! 相信对大家学习C语言会有很大帮助!!!
c语言学习笔记-简易版扫雷
写得蛮好的linux学习笔记--linux目录架构
C语言学习笔记-详细而全面的基础教程.pdf
linux内核移植 笔记--移植指令 linux内核移植 笔记--移植指令 linux内核移植 笔记--移植指令
JXW的C语言学习笔记-待查
Linux课程学习笔记 -韩顺平 包含c/c++/python/java 专项 面试题 PDF PPT 笔记 面试题 (百度网盘链接 永久有效) 自学,做笔记,复习可用
armlinux学习笔记--触摸屏驱动程序分析.pdf
Linux学习笔记Linux学习笔记Linux学习笔记Linux学习笔记
linux学习笔记-01linux操作基础
Linux学习笔记-超全总结值得一看(带标签目录),共154页。
找到的一篇写的很好的linux学习笔记 不敢独享 大家有兴趣的就下下
armlinux学习笔记--IIS音频驱动程序分析(2).pdf
armlinux学习笔记--IIS音频驱动程序分析(2)资料.pdf
python爬虫学习笔记-scrapy框架(1) python scrapy 爬虫 python爬虫学习笔记-scrapy框架(1) python scrapy 爬虫 python爬虫学习笔记-scrapy框架(1) python scrapy 爬虫 python爬虫学习笔记-scrapy框架(1) python ...