标签:
有的时候,我们需要在一个基础中同时运行多个控制流程。例如:一个图形界面的下载软件,在处理下载任务的同时,还必须响应界面的对任务的停止,删除等控制操作。这个时候就需要用到线程来实现并发操作。
和信号处理函数的控制在处理完信号之后就结束不同的是,多线程的控制流程可以长期并存,操作系统会在各线程之间调度和切换,就像在多个进程之间调度和切换一样,但创建线程开销要比进程小得多。因此,线程往往也被称作轻量级的进程。
由于同一进程的多个线程共享同一地址空间,数据段是共享的,如果定义一个全局变量,在各线程中都可以访问到。但有,些资源依然是每个线程各有一份的:
我们一般用到的是由POSIX标准定义的线程库函数,称为POSIX thread或者pthread。在Linux上线程函数位于libpthread共享库中,因此在编译时要加上-lpthread选项。
在POSIX库中,创建线程是通过函数实现的,它的声明如下:
#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
它有四个参数,
创建成功时,返回0,失败是返回错误码。这个和其它的系统函数失败返回-1,由errno返回错误码不大一样。
有的时候,我们需要等待线程结束,此时才能继续执行后面的事情。拿前面的例子来说,如果不等待线程结束,则主线程(main函数)会直接往下执行导致程序退出,线程函数都无法得到执行。
pthread库中等待线程结束的函数是pthread_join,它的声明如下:
#include <pthread.h>
int pthread_join(pthread_t thread, void **retval);
它有两个参数,
终止线程的方法一般来说有如下几种:
其中,方法1和方法2都是通过结束线程函数来实现主动退出的,它们是比较常用的方法。方法3则是一种强制终止的做法,这个方法一个问题就是导致对象的析构函数可能无法执行,会出现资源泄漏,并不推荐用这种方法。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
void* thr_fn(void *arg)
{
pid_t pid = getpid();
pthread_t tid = pthread_self();
printf("%s pid %u tid %u (0x%x)\n", arg, (unsigned int)pid, (unsigned int)tid, (unsigned int)tid);
return NULL;
}
int main(void)
{
pthread_t ntid = {0};
int err = pthread_create(&ntid, NULL, thr_fn, (void*)"new thread: ");
if (err != 0)
{
fprintf(stderr, "can‘t create thread: %s\n", strerror(err));
exit(1);
}
void *tret;
pthread_join(ntid, &tret);
printf("thread exited\n");
return 0;
}
编译程序
gcc thread.c -o thread -lpthread
运行结果
new thread: pid 21231 tid 1082132800 (0x40800940)
thread exited
标签:
原文地址:http://www.cnblogs.com/linzhenjie/p/5485677.html