Pthread多线程编程之线程创建和终止及参数传递

POSIX线程(POSIX threads),简称Pthreads,是线程的POSIX标准。该标准定义了创建和操纵线程的一整套API。POSIX线程具有很好的可移植性,使用pthreads编写的代码可运行于Solaris、FreeBSD、Linux 等平台,Windows平台亦有pthreads-win32可供使用。

Pthreads定义了一套C语言的类型、函数与常量,它以pthread.h头文件和一个线程库实现。

一、 创建和终止线程

#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
void pthread_exit(void *retval);
int pthread_cancel(pthread_t thread);

pthread_create功能是创建线程(实际上就是确定调用该线程函数的入口点),在线程创建以后,就开始运行相关的线程函数。
pthread_create的返回值:表示成功,返回0;表示出错,返回-1。

thread:指向线程标识符的指针
attr:用来设置线程属性,可以指定线程属性对象,或者为默认值指定NULL
start_routine:线程运行函数的起始地址
arg:运行函数的参数,如果不传递参数,则可以使用NULL

二、 Joining and Detaching线程

pthread_detach()和pthread_join()就是控制子线程回收资源的两种不同的方式。同一进程间的线程具有共享和独立的资源,其中共享的资源有堆、全局变量、静态变量、文件等公用资源。而独享的资源有栈和寄存器,这两种方式就是决定子线程结束时如何回收独享的资源。
pthread_detach()即主线程与子线程分离,两者相互不干涉,子线程结束同时子线程的资源自动回收。pthread_join()即是子线程合入主线程,主线程会一直阻塞,直到子线程执行结束,然后回收子线程资源,并继续执行。

#include <pthread.h>
int pthread_join(pthread_t thread, void **retval);
int pthread_detach(pthread_t thread);
#include <stdio.h>
#include <pthread.h>
#define NUM_THREADS 10

void *sayhello(void *tid)
{
	int threadno = *(int *)tid;
	printf("Hello, thread: %d\n", threadno);
	pthread_exit(NULL);
}

int main(void)
{
	pthread_t threads[NUM_THREADS];
	int threadno[NUM_THREADS], retval;

	for(int i=0; i<NUM_THREADS; i++)
	{
		printf("Creating thread: %d\n", i);
		threadno[i] = i;
		retval = pthread_create(&threads[i], NULL, sayhello, (void *)&threadno[i]);

		if(retval != 0)
		{
			printf("pthread_create error\n");
			return 1;
		}
	}

	for(int i=0; i<NUM_THREADS; i++)
	{
		retval = pthread_join(threads[i], NULL);

		if(retval != 0)
		{
			printf("pthread_join error\n");
			return 1;
		}
	}

	pthread_exit(NULL);
	return 0;
}
[ycxie@fedora Workspace]$ gcc pthreaddemo.c -o pthreaddemo -pthread
[ycxie@fedora Workspace]$ ./pthreaddemo
Creating thread: 0
Creating thread: 1
Creating thread: 2
Hello, thread: 1
Creating thread: 3
Hello, thread: 2
Creating thread: 4
Hello, thread: 3
Hello, thread: 0
Creating thread: 5
Hello, thread: 4
Creating thread: 6
Hello, thread: 5
Creating thread: 7
Hello, thread: 6
Hello, thread: 7
Creating thread: 8
Creating thread: 9
Hello, thread: 8
Hello, thread: 9

三、 参数传递

#include <stdio.h>
#include <string.h>
#include <pthread.h>
#define NUM_THREADS 5

struct student
{
	int id;
	char name[100];
	char addr[100];
};

void *sayhello(void *arg)
{
	struct student *p = (struct student *)arg;
	printf("%d\t%s\t%s\n", p->id, p->name, p->addr);
	pthread_exit(NULL);
}

int main(void)
{
	pthread_t threads[NUM_THREADS];
	struct student data[NUM_THREADS];
	int retval;

	data[0].id = 0;
	strcpy(data[0].name, "Xie Yincai");
	strcpy(data[0].addr, "Beijing China");

	data[1].id = 1;
	strcpy(data[1].name, "Barack Obama");
	strcpy(data[1].addr, "United States of America");

	data[2].id = 2;
	strcpy(data[2].name, "Dennis Ritchie");
	strcpy(data[2].addr, "United States of America");

	data[3].id = 3;
	strcpy(data[3].name, "Donald Trump");
	strcpy(data[3].addr, "United States of America");

	data[4].id = 4;
	strcpy(data[4].name, "Michael Jordan");
	strcpy(data[4].addr, "United States of America");

	for(int i=0; i<NUM_THREADS; i++)
	{
		printf("Creating thread: %d\n", i);
		retval = pthread_create(&threads[i], NULL, sayhello, (void *)&data[i]);

		if(retval != 0)
		{
			printf("pthread_create error\n");
			return 1;
		}
	}

	for(int i=0; i<NUM_THREADS; i++)
	{
		retval = pthread_join(threads[i], NULL);

		if(retval != 0)
		{
			printf("pthread_join error\n");
			return 1;
		}
	}

	pthread_exit(NULL);
	return 0;
}
[ycxie@fedora Workspace]$ ./pthreaddemo
Creating thread: 0
Creating thread: 1
0	Xie Yincai	Beijing China
1	Barack Obama	United States of America
Creating thread: 2
Creating thread: 3
2	Dennis Ritchie	United States of America
Creating thread: 4
3	Donald Trump	United States of America
4	Michael Jordan	United States of America

Leave a Reply

Your email address will not be published. Required fields are marked *