创建线程是每个linux开发者都会用到的。在这里介绍一下pthread_create()函数。我们来看一看怎么创造一个线程。
首先查看pthread_create()函数的定义:
PTHREAD_CREATE(3) Linux Programmer's Manual PTHREAD_CREATE(3)
NAME top
pthread_create - create a new thread
SYNOPSIS top
#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
Compile and link with -pthread.
DESCRIPTION top
The pthread_create() function starts a new thread in the calling
process. The new thread starts execution by invoking
start_routine(); arg is passed as the sole argument of
start_routine().
The new thread terminates in one of the following ways:
* It calls pthread_exit(3), specifying an exit status value that is
available to another thread in the same process that calls
pthread_join(3).
* It returns from start_routine(). This is equivalent to calling
pthread_exit(3) with the value supplied in the return statement.
* It is canceled (see pthread_cancel(3)).
* Any of the threads in the process calls exit(3), or the main thread
performs a return from main(). This causes the termination of all
threads in the process.
The attr argument points to a pthread_attr_t structure whose contents
are used at thread creation time to determine attributes for the new
thread; this structure is initialized using pthread_attr_init(3) and
related functions. If attr is NULL, then the thread is created with
default attributes.
Before returning, a successful call to pthread_create() stores the ID
of the new thread in the buffer pointed to by thread; this identifier
is used to refer to the thread in subsequent calls to other pthreads
functions.
The new thread inherits a copy of the creating thread's signal mask
(pthread_sigmask(3)). The set of pending signals for the new thread
is empty (sigpending(2)). The new thread does not inherit the
creating thread's alternate signal stack (sigaltstack(2)).
The new thread inherits the calling thread's floating-point
environment (fenv(3)).
The initial value of the new thread's CPU-time clock is 0 (see
pthread_getcpuclockid(3)).
Linux-specific details
The new thread inherits copies of the calling thread's capability
sets (see capabilities(7)) and CPU affinity mask (see
sched_setaffinity(2)).
RETURN VALUE top
On success, pthread_create() returns 0; on error, it returns an error
number, and the contents of *thread are undefined.
ERRORS top
EAGAIN Insufficient resources to create another thread.
EAGAIN A system-imposed limit on the number of threads was
encountered. There are a number of limits that may trigger
this error: the RLIMIT_NPROC soft resource limit (set via
setrlimit(2)), which limits the number of processes and
threads for a real user ID, was reached; the kernel's system-
wide limit on the number of processes and threads,
/proc/sys/kernel/threads-max, was reached (see proc(5)); or
the maximum number of PIDs, /proc/sys/kernel/pid_max, was
reached (see proc(5)).
EINVAL Invalid settings in attr.
EPERM No permission to set the scheduling policy and parameters
specified in attr.
说了这么一大通,我看关键是看这个函数的参数和返回值。参数一共用到四个:
第一个是指向线程标识符的指针,类型为pthread_t
第二个是用来设置线程的属性
第三个是线程运行的起始地址,其实就是你自己定义的执行函数
第四个就是运行函数所传入的参数
在这里还要介绍另外一个函数,int pthread_join(pthread_t thread, void **retval);
这个函数一共用到两个参数:
第一个是线程标识符,类型为pthread_t
第二个是retval: 用户定义的指针,可以用来存储被等待线程的返回值。
下面我们给出一个例子:
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
struct sum{
int num_a;
int num_b;
char * string;
};
static void * pthread_handle(void * arg)
{
struct sum *mSum;
mSum=(struct sum *)arg;
printf("pthread_handle start runnig!\n");
sleep(1);
printf("%s\n",mSum->string);
printf("sum result:%d\n",mSum->num_a+mSum->num_b);
}
int main(int agrc,char* argv[])
{
pthread_t mTidp;
struct sum *m;
m=(struct sum *)malloc(sizeof(struct sum));
m->num_a=1;
m->num_b=2;
m->string="Do sum";
if (pthread_create(&mTidp, NULL, pthread_handle, (void*)m) == -1)
{
printf("create pthread error!\n");
return 1;
}
sleep(1);
if (pthread_join(mTidp, NULL))
{
printf("There is something wrong here\n");
return -1;
}
return 0;
}
编译:
gcc -o pthread_test -pthread pthread_test.c
//注意一定要加上 -pthread,因为pthread并非Linux系统的默认库,而是POSIX线程库。
//在Linux中将其作为一个库来使用,因此加上 -pthread 以显式链接该库
运行:
y@ubuntu:~/project/pthread_test$ ./pthread_test
pthread_handle start runnig!
Do sum
sum result:3