为新线程传入一个参数实例:
源码:
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; }