多线程程序设计1
来源:互联网 发布:国内域名资源分布状况 编辑:程序博客网 时间:2024/04/27 21:31
说明:只供学习交流,转载请注明出处
一,创建线程和退出线程
在Linux系统中,所有与线程相关的函数都是以pthread开头的。pthread_create函数用于在当前进程中加入新的线程。Linux系统中线程的创建与UNIX系统存在着不同。在Linux系统中,当调用pthread_create函数来创建线程时,系统首先先创建一个新的进程,再在该进程内再创建需要的线程。新创建的进程与原有的进程是共享内存的,因此,与调用fork而产生的进程存在着本质的区别。同时,在第一次调用pthread_create函数时,系统还会创建一个管理进程,用于对多线程的管理。
头文件
#include <pthread.h>
函数原型
int pthread_create(pthread_t * tidp,
const pthread_attr_t *attr,
void *(*start_rtn)(void), void *arg)
返回值
成功
失败
是否设置errno
0
-1
是
函数功能:创建新的线程
参数说明:tidp:线程id attr:线程属性(通常为空) start_rtn:线程要执行的函数 arg:start_rtn的参数
说明:新的线程将拥有自己的堆。同时,从创建线程处继承调度优先级。如果pthread_create函数调用失败,将不会创建新的线程。
错误信息:
EAGAIN:系统没有足够的资源来创建新的线程,或系统达到最大线程数(PTHREAD_THREADS_MAX)。
EINVAL:参数attr非法。
EPERM:函数调用者没有相应的设置线程调度参数或策略的权限。
注意:因为pthread的库不是linux系统的库,所以在进行编译的时候要加上-lpthread
# gcc filename –lpthread
实例:
程序为使用pthread_create函数来创建线程的实例。在程序中调用pthread_create函数来启动新的线程。调用sleep函数的目的是保证进程在新线程运行之前不会退出。具体代码如下:
#include <stdio.h>#include <pthread.h>#include <unistd.h>void *thread_info(void){printf("In thread_info function!\n");return NULL;}int main(void){pthread_t thread_id;int ret;//创建线程ret = pthread_create(&thread_id, NULL, (void*)thread_info, NULL);if (ret == -1){perror("Cannot create new thread!");return (1);}//保证主线程会在创建线程执行完成之后结束sleep(5);return (0);}运行结果:[root@localhost test]# gcc -Wall -lpthread pthread_create.c -o pthread_create[root@localhost test]# ./pthread_create In thread_info function![root@localhost test]#
补充:
函数pthread_tpthread_self(void)
功能:获取调用线程的threadidentifier(线程ID)。
二,pthread_exit函数
如果进程中任何一个线程中调用exit或_exit,那么整个进程都会终止。线程的正常退出方式有以下几种:
(1):创建线程时指定要执行的函数执行完毕。
(2):创建线程的进程退出。
(3):某个线程调用了exec函数。
(4):线程调用了pthrea_exit函数退出。
(5):线程被pthread_cancel终止。
从上面可以了解到使用pthread_exit函数可以让运行的进程退出。pthread_exit函数的具体信息如下所示:
pthread_exit函数
头文件
#include <pthread.h>
函数原型
void pthread_exit(void *value_ptr);
返回值
成功
失败
是否设置errno
——
——
——
说明:pthread_exit函数用于结束线程的运行。参数value_ptr设置线程退出的返回值。由于value_ptr为指向内存空间的指针,value_ptr必须指向线程退出后任然存在的空间,value_ptr指针不能执行局部变量。
如果在进程的main函数中调用pthread_exit函数,主函数所在的线程将退出。但是使用return的话,实际上进程将退出,从而导致所有的线程退出。如果return包含在pthread_cleanup_push函数和pthread_cleanup_pop函数之间,那么线程将不会调用清理函数,程序将提示出现段错误。
三,线程等待
创建一个线程,在进程中通过调用函数pthread_join等待线程结束,这个函数是一个线程阻塞的函数,调用它的进程将一直等待直到被等待的线程结束为止,当函数返回时,被等待线程的资源被回收。具体函数如下:
pthread_join函数
头文件
#include <pthread.h>
函数原型
int pthread_join(pthread_t thread,
void **value_ptr);
返回值
成功
失败
是否设置errno
0
非0值
是
函数功能:等待一个线程结束
参数说明:thread为要等待的线程标识符;value_ptr为一个用户自定义的指针,它可以用来存储被等待进程的返回值。
错误信息:
EINVAL:参数thread中指定的线程为非可连接的线程。
ESRCH:无thread参数指定的线程。
EDEADLK:指定线程中存在死锁。
实例:
#include <stdio.h>#include <pthread.h>//用于保存线程中要显示的信息的结构体struct thread_param{char info;int num;};//线程要执行的函数void *thread_fun(void *param){struct thread_param *p;p = (struct thread_param*)param;int i;for (i = 0; i < p->num; i++){printf("%i: %c\n", i, p->info);}return (NULL);}int main(void){pthread_t tid1, tid2;struct thread_param info1;struct thread_param info2;int ret;info1.info = 'T';info1.num = 2;//创建线程,线程要执行的函数参数为info1ret = pthread_create(&tid1, NULL, thread_fun, (void *)&info1);if (ret == -1){perror("Cannot create new pthread");return (1);}info2.info = 'S';info2.num = 3;//创建线程,线程要执行的函数参数为info2ret = pthread_create(&tid2, NULL, thread_fun, (void *)&info2);if (ret == -1){perror("Cannot create new pthread");return (1);}//等待创建的线程tid1的结束if (pthread_join(tid1, NULL) != 0){perror("Call pthread_join function fail");return (1);}//等待创建的线程tid2的结束if (pthread_join(tid2, NULL) != 0){perror("Call pthread_join function fail");return (1);}return (0);}运行结果:[root@localhost test]# ./pthread_join 0: T1: T0: S1: S2: S[root@localhost test]#
- Windows程序设计---多线程1
- Windows程序设计---多线程1
- Java多线程程序设计1
- 多线程程序设计1
- Java多线程程序设计初步(1)
- 《win32多线程程序设计》随笔1
- 多线程程序设计
- 多线程程序设计
- 多线程程序设计
- 多线程程序设计
- 多线程程序设计
- 多线程程序设计
- 多线程程序设计
- 多线程程序设计
- 多线程程序设计
- 多线程程序设计
- DELPHI下的多线程程序设计(1)
- Win32多线程程序设计学习笔记 1
- 在函数中使用二维数组做参数
- android和PC本地服务器地址
- 算法分析与设计之五大常用算法 (III)—— 贪心算法
- 线程理论基础
- 维度照相机
- 多线程程序设计1
- 如何判断一个数是否为素数
- Android之adb环境变量配置标签
- RMAN 备份
- 多线程程序设计2
- 常见的java笔试题
- 让Java代码跑得更快
- (转)hibernate常用API详解
- 联想G460更新显卡驱动无法更改屏幕亮度的解决办法