为新线程传入一个参数实例:
源码:
robin@ubuntu:~/workspace/c_workspace/pthread$ cat thread.c
/*************************************************
* pthread_create() pthread_join() 实例
*
* **********************************************/
#include <stdio.h>
#include <pthread.h>
void *start_routine(void *arg){
int i = 300;
int j = *(int*)arg; /* 注意这里必须强转 */
printf("[start_routine] New thread is called!!!!\n");
printf("i + j = %d\n", i, j, i+j);
return (void*)0;
}
int main(int argc, char **argv, char **envp){
pthread_t p_id;
int i = 500;
printf("[main] Main thread is executing!!!!!\n");
pthread_create(&p_id, NULL, start_routine, (void*)&i); /*这里i也必须强转, p_id 必须传引用,不能是指针*/
pthread_join(p_id, NULL); /*用来等待新线程执行结束,一个 p_id 只能被等待一次*/
return 0;
}
Makefile:
robin@ubuntu:~/workspace/c_workspace/pthread$ cat Makefile
CC=gcc
SRC=thread.c
OBJ=thread
all: $(SRC)
$(CC) $(SRC) -o $(OBJ) -lpthread
执行结果:
robin@ubuntu:~/workspace/c_workspace/pthread$ ./thread
[main] Main thread is executing!!!!!
[start_routine] New thread is called!!!!
i + j = 300
为新线程传入多个参数实例:
/*****************************************************************
*学习多线程经典例子,来源于 man pthread_create()
*
* Robin
*
* **************************************************************/
#include <stdio.h>
#include <errno.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h> //for strdup()
#include <string.h> //for toupper()
#define handle_error_en(en, msg) \
do { errno = en; perror(msg); exit(EXIT_FAILURE); } while(0)
#define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while(0)
/******************************************************
*定义数组,用来为pthread_create()函数传递多个参数。
* 其只能接收一个参数,要传递多个参数,就必须用数组
* 来传递
*****************************************************/
struct thread_info{
pthread_t thread_id;
int thread_num;
char *argv_string;
};
/* Thread start function: display address near top of our stack,
* and return upper-caseed copy of argv_string */
/**************************************************************
*void * thread_start(void *arg) 新创建的线程将会执行该函数。
* 需要注意的是,参数和返回值都是void*,在传参的时候注意强转。
* ************************************************************/
static void * thread_start(void *arg){
struct thread_info *tinfo = (struct thread_info *) arg;
char *uargv, *p;
printf("Thread %d: top of stack near %p; argv_string=%s\n",
tinfo->thread_num, &p, tinfo->argv_string);
uargv = strdup(tinfo->argv_string);
if (uargv == NULL)
handle_error("strdup");
for (p = uargv; *p != '\0'; p++)
*p = toupper(*p);
return uargv;
}
int main(int argc, char** argv, char** envpv){
int s, tnum, opt, num_threads;
struct thread_info *tinfo;
pthread_attr_t attr;
int stack_size;
void *res;
stack_size = -1;
/************************************************************
* 使用getopt()获取,从main的argc,argv中获取命令行选项和参数
* *********************************************************/
while ((opt = getopt(argc, argv, "s:")) != -1){
switch (opt) {
case 's':
stack_size = strtoul(optarg, NULL, 0);
break;
default:
fprintf(stderr, "Usage: %s [-s stack-size] arg...\n",argv[0]);
exit(EXIT_FAILURE);
}
}
num_threads = argc - optind;//????????????
/* Initialize thread creation attributes */
/**********************************************************
*初始化线程的各种属性。
*********************************************************/
s = pthread_attr_init(&attr);
if (s != 0)
handle_error_en(s, "pthread_attr_init");
if (stack_size > 0){
/***********************************************************
* 设置线程的堆栈大小属性。
* ********************************************************/
s = pthread_attr_setstacksize(&attr, stack_size);
if (s != 0){
handle_error_en(s, "pthread_attr_setstacksize");
}
}
/*Allocate memory for pthread_create() arguments */
/*****************************************************************
*为num_threads个线程传入的参数分配内存
* **************************************************************/
tinfo = (struct thread_info*)calloc(num_threads,sizeof(struct thread_info));
if (tinfo == NULL)
handle_error("calloc");
/* Create one thread for each command-line argument */
for (tnum = 0; tnum < num_threads; tnum++) {
tinfo[tnum].thread_num = tnum +1;
tinfo[tnum].argv_string = argv[optind + tnum];
/* The pthread_create() call stores the thread ID into
* corresponding element of tinfo[] */
/********************************************************
*创建线程:
*&attr 线程的属性
* &tinfo[tnum].thread_id(传引用来存储线程id)
* &thread_start 新线程要执行的函数
* &tinfo[tnum] 为新线程传入的参数
* *****************************************************/
s = pthread_create(&tinfo[tnum].thread_id, &attr,
&thread_start, &tinfo[tnum]);
if (s != 0)
handle_error_en(s, "pthread_create");
}
/* Destroy the thread attributes object, since it is no
* longer needed */
s = pthread_attr_destroy(&attr);
if (s != 0)
handle_error_en(s, "pthread_attr_destroy");
/* Now join with each thread, and display its returned value */
for ( tnum = 0; tnum < num_threads; tnum++ ){
/*********************************************************
*等待新线程tinfo[tnum].thread_id执行结束,主线程才能结束
*&res 新线程的返回值
* ******************************************************/
s = pthread_join(tinfo[tnum].thread_id, &res);
if (s != 0){
handle_error_en(s, "pthread_join");
}
printf("Joined with thread %d; returned value was %s\n",
tinfo[tnum].thread_num,(char *)res);
free(res); /* Free memory allocated by thread */
}
free(tinfo);
exit(EXIT_SUCCESS);
}
在此收录多线程编程的链接:
出租车(taxi)的多线程问题(摘自上面链接):
#include <stdio.h>
#include <pthread.h>
pthread_cond_t taxiCond;
pthread_mutex_t taxiMutex;
int travelerCount = 0;
void *traveler_arrive(void * name){
printf(" Traveler: %s needs a taxi now!!!\n", (char*)name);
pthread_mutex_lock(&taxiMutex);
travelerCount++;
pthread_cond_wait(&taxiCond, &taxiMutex);
pthread_mutex_unlock(&taxiMutex);
printf(" Traveler: %s got a taxi now!!!\n", (char*)name);
pthread_exit((void*)0);
}
void * taxi_arrive(void* name){
printf(" Taxi: %s arrives.\n", (char*)name);
while(1){
pthread_mutex_lock(&taxiMutex);
if(travelerCount > 0){
pthread_cond_signal(&taxiCond);
pthread_mutex_unlock(&taxiMutex);
break;
}
pthread_mutex_unlock(&taxiMutex);
}
pthread_exit((void *)0);
}
int main(int argc, char** argv, char** envp){
pthread_cond_init(&taxiCond, PTHREAD_PROCESS_PRIVATE);
pthread_mutex_init(&taxiMutex, NULL);
pthread_t thread;
pthread_attr_t threadAttr;
pthread_attr_init(&threadAttr);
pthread_create(&thread, & threadAttr, taxi_arrive, (void *)( " Jack " ));
sleep(1);
pthread_create(&thread, &threadAttr, traveler_arrive, (void *)( " Susan " ));
sleep(1);
pthread_create(&thread, &threadAttr, taxi_arrive, (void *)( " Mike " ));
sleep(1);
pthread_cond_destroy(&taxiCond);
return 0;
}