pthread系列函数实例学习(一)

 

为新线程传入一个参数实例:

源码:

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;    
}



 

 

 

 

 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值