多线程编程实例练习

pthread_join使一个线程等待另一个线程结束。代码中如果没有pthread_join主线程会很快结束从而使整个进程结束,从而使创建的线程没有机会开始执行就结束了。加入pthread_join后,主线程会一直等待直到等待的线程结束自己才结束,使创建的线程有机会执行。

#include <pthread.h>  
#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  

void *thread_function(void *arg);    
char message[] = "Hello World";  

int main()  
{  
    int res;  
    pthread_t a_thread;  
    void *thread_result;  

    res = pthread_create(&a_thread, NULL, thread_function, (void *)message);  
    if (res != 0)  
    {  
        perror("Thread creation failed!");  
        exit(EXIT_FAILURE);  
    }  

    printf("Waiting for thread to finish...\n");  

    res = pthread_join(a_thread, &thread_result);  
    if (res != 0)  
    {  
        perror("Thread join failed!\n");  
        exit(EXIT_FAILURE);  
    }  

    printf("Thread joined, it returned %s\n", (char *)thread_result);  
    printf("Message is now %s\n", message);  

    exit(EXIT_FAILURE);  
}  

void *thread_function(void *arg)  
{  
    printf("thread_function is running. Argument was %s\n", (char *)arg);  
    sleep(3);  
    strcpy(message, "Bye!");  
    pthread_exit("Thank you for your CPU time!");  
}  

线程同步

#include <pthread.h>  
#include <stdio.h>  
#include <stdlib.h>  

int flag = 1;    
void *thread_function(void *arg);  

int main()  
{  
    int res;  
    pthread_t a_thread;  
    void *thread_result;  
    int count = 1;  

    res = pthread_create(&a_thread, NULL, thread_function, NULL);  
    if (res != 0)  
    {  
        perror("Thread creation failed");  
        exit(EXIT_FAILURE);  
    }  

    while (count++ <= 20)  
    {  
        if (flag == 1)  
        {  
            printf ("1");  
            flag = 2;  
        }  
        else  
        {  
            sleep(1);  
        }  
    }  

    printf("\nWaiting for thread to finish...\n");  
    res = pthread_join(a_thread, &thread_result);  
    if (res != 0)  
    {  
        perror("Thread join failed");  
        exit(EXIT_FAILURE);  
    }  

    exit(EXIT_SUCCESS);  
}  

void *thread_function(void *arg)  
{  
    int count = 1;  

    while (count++ <= 20)  
    {  
        if (flag == 2)  
        {  
            printf("2");  
            flag = 1;  
        }  
        else  
        {  
            sleep(1);  
        }  
    }  
}  

设置线程为detachstate属性。表示新线程是否与进程中其他线程脱离同步,如果设置为PTHREAD_CREATE_DETACHED则新线程不能用pthread_join()来同步,且在退出时自行释放所占用的资源。缺省为PTHREAD_CREATE_JOINABLE状态。这个属性也可以在线程创建并运行以后用pthread_detach()来设置,而一旦设置为PTHREAD_CREATE_DETACH状态(不论是创建时设置还是运行时设置)则不能再恢复到PTHREAD_CREATE_JOINABLE状态

#include <stdio.h>  
#include <unistd.h>  
#include <stdlib.h>  
#include <pthread.h>  

void *thread_function(void *arg);  

char message[] = "Hello World";  
int thread_finished = 0;  

int main()  
{  
    int res;  
    pthread_t a_thread;  
    pthread_attr_t thread_attr;  

    res = pthread_attr_init(&thread_attr);  
    if (res != 0)  
    {  
        perror("Attribute creation failed");  
        exit(EXIT_FAILURE);  
    }  

    res = pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);  
    if (res != 0)  
    {  
        perror("Setting detached attribute failed");  
        exit(EXIT_FAILURE);  
    }  

    res = pthread_create(&a_thread, &thread_attr, thread_function, (void*)message);  
    if (res != 0)  
    {  
        perror("Thread creation failed");  
        exit(EXIT_FAILURE);  
    }  

    pthread_attr_destroy(&thread_attr);  
    while(!thread_finished)  
    {  
        printf("Waiting for thread to say it's finished...\n");  
        sleep(1);  
    }  

    printf("Other thread finished, bye!\n");  
    exit(EXIT_SUCCESS);  
}  

void *thread_function(void *arg)  
{  
    printf("thread_function is running. Argument was %s\n", (char *)arg);  
    sleep(4);  
    printf("Second thread setting finished flag, and exiting now\n");  
    thread_finished = 1;  
    pthread_exit(NULL);  
}  

线程的被动结束分为两种,一种是异步终结,另外一种是同步终结。异步终结就是当其他线程调用 pthread_cancel的时候,线程就立刻被结束。而同步终结则不会立刻终结,它会继续运行,直到到达下一个结束点(cancellation point)

#include <pthread.h>  
#include <stdio.h>  
#include <stdlib.h>  

void *thread_function(void *arg);  

int main()  
{  
    int res;  
    pthread_t a_thread;  
    void *thread_result;  

    res = pthread_create(&a_thread, NULL, thread_function, NULL);  
    if (res != 0)  
    {  
        perror("Thread create failed!");  
        exit(EXIT_FAILURE);  
    }  

    sleep(4);  
    printf("Canceling thread...\n");  

    res = pthread_cancel(a_thread);  
    if (res != 0)  
    {  
        perror("Thread cancel failed!");  
        exit(EXIT_FAILURE);  
    }  

    printf ("Waiting for thread to finished...\n");  

    res = pthread_join(a_thread, &thread_result);  
    if (res != 0)  
    {  
        perror ("Thread join failed!");  
        exit(EXIT_FAILURE);  
    }  

    printf("Thread canceled!");  

    exit(EXIT_FAILURE);  
}  

void *thread_function(void *arg)  
{  
    int i;  
    int res;  

    res = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);  
    if (res != 0)  
    {  
        perror("Thread setcancelstate failed!");  
        exit(EXIT_FAILURE);  
    }  

    res = pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);  
    if (res != 0)  
    {  
        perror("Thread setcanceltype failed!");  
        exit(EXIT_FAILURE);  
    }  

    printf("thread_function is running...\n");  

    for (i = 0; i < 10; i++)  
    {  
        printf("Thread is still running (%d)...\n", i);  
        sleep(1);  
    }  
    pthread_exit(0);  
}  

多线程编程

#include <pthread.h>  
#include <stdio.h>  
#include <stdlib.h>  

#define NUM 6  

void *thread_function(void *arg);  

int main()  
{  
    int res;  
    pthread_t a_thread[NUM];  
    void *thread_result;  
    int index;  

    for (index = 0; index < NUM; ++index) {  
        res = pthread_create(&a_thread[index], NULL, thread_function, (void *)index);  
        if (res != 0)  
        {  
            perror("Thread create failed!");  
            exit(EXIT_FAILURE);  
        }  
        sleep(1);  
    }  

    printf("Waiting for threads to finished...\n");  

    for (index = NUM - 1; index >= 0; --index)  
    {  
        res = pthread_join(a_thread[index], &thread_result);  
        if (res == 0)  
        {  
            printf("Picked up a thread:%d\n", index + 1);  
        }  
        else  
        {  
            perror("pthread_join failed\n");  
        }  
    }  

    printf("All done\n");  

    exit(EXIT_SUCCESS);  
}  

void *thread_function(void *arg)  
{  
    int my_number = (int)arg;  
    int rand_num;  

    printf("thread_function is running. Argument was %d\n", my_number);  
    rand_num = 1 + (int)(9.0 * rand()/(RAND_MAX + 1.0));  
    sleep(rand_num);  
    printf("Bye from %d\n", my_number);  
    pthread_exit(NULL);  
}  

使用信号量进行线程同步

#include <pthread.h>  
#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <semaphore.h>  

#define SIZE 1024   
void *thread_function(void *arg);  

char buffer[SIZE];  
sem_t sem;  

int main()  
{  
    int res;  
    pthread_t a_thread;  
    void *thread_result;  

    res = sem_init(&sem, 0, 0);  
    if (res != 0)  
    {  
        perror("Sem init failed");  
        exit(EXIT_FAILURE);  
    }  

    res = pthread_create(&a_thread, NULL, thread_function, NULL);  
    if (res != 0)  
    {  
        perror("Thread create failed");  
        exit(EXIT_FAILURE);  
    }  

    printf("Input some text. Enter 'end' to finish\n");  

    while (scanf("%s", buffer))  
    {  
        sem_post(&sem);  
        if (strncmp("end", buffer, 3) == 0)  
            break;  
    }  

    printf ("\nWaiting for thread to finish...\n");  

    res = pthread_join(a_thread, &thread_result);  
    if (res != 0)  
    {  
        perror("Thread join failed");  
        exit(EXIT_FAILURE);  
    }  

    printf ("Thread join\n");  

    sem_destroy(&sem);    
    exit(EXIT_SUCCESS);  
}  

void *thread_function(void *arg)  
{  
    sem_wait(&sem);  
    while (strncmp("end", buffer, 3) != 0)  
    {  
        printf("You input %d characters\n", strlen(buffer));  
        sem_wait(&sem);  
    }  
    pthread_exit(NULL);  
}   

线程优先级调度

#include <stdio.h>
#include <pthread.h>
#include <sched.h>
#include <assert.h>

static int api_get_thread_policy (pthread_attr_t *attr)
{
    int policy;
    int rs = pthread_attr_getschedpolicy (attr, &policy);
    assert (rs == 0);

    switch (policy)
    {
        case SCHED_FIFO:
            printf ("policy = SCHED_FIFO\n");
            break;
        case SCHED_RR:
            printf ("policy = SCHED_RR");
            break;
        case SCHED_OTHER:
            printf ("policy = SCHED_OTHER\n");
            break;
        default:
            printf ("policy = UNKNOWN\n");
            break; 
    }
    return policy;
}

static void api_show_thread_priority (pthread_attr_t *attr,int policy)
{
    int priority = sched_get_priority_max (policy);
    assert (priority != -1);
    printf ("max_priority = %d\n", priority);
    priority = sched_get_priority_min (policy);
    assert (priority != -1);
    printf ("min_priority = %d\n", priority);
}

static int api_get_thread_priority (pthread_attr_t *attr)
{
    struct sched_param param;
    int rs = pthread_attr_getschedparam (attr, &param);
    assert (rs == 0);
    printf ("priority = %d\n", param.__sched_priority);
    return param.__sched_priority;
}

static void api_set_thread_policy (pthread_attr_t *attr,int policy)
{
    int rs = pthread_attr_setschedpolicy (attr, policy);
    assert (rs == 0);
    api_get_thread_policy (attr);
}

int main(void)
{
    pthread_attr_t attr;       // 线程属性
    struct sched_param sched;  // 调度策略
    int rs;

    /* 
     * 对线程属性初始化
     * 初始化完成以后,pthread_attr_t 结构所包含的结构体
     * 就是操作系统实现支持的所有线程属性的默认值
     */
    rs = pthread_attr_init (&attr);
    assert (rs == 0);     // 如果 rs 不等于 0,程序 abort() 退出

    /* 获得当前调度策略 */
    int policy = api_get_thread_policy (&attr);

    /* 显示当前调度策略的线程优先级范围 */
    printf ("Show current configuration of priority\n");
    api_show_thread_priority(&attr, policy);

    /* 获取 SCHED_FIFO 策略下的线程优先级范围 */
    printf ("show SCHED_FIFO of priority\n");
    api_show_thread_priority(&attr, SCHED_FIFO);

    /* 获取 SCHED_RR 策略下的线程优先级范围 */
    printf ("show SCHED_RR of priority\n");
    api_show_thread_priority(&attr, SCHED_RR);

    /* 显示当前线程的优先级 */
    printf ("show priority of current thread\n");
    int priority = api_get_thread_priority (&attr);

    /* 手动设置调度策略 */
    printf ("Set thread policy\n");

    printf ("set SCHED_FIFO policy\n");
    api_set_thread_policy(&attr, SCHED_FIFO);

    printf ("set SCHED_RR policy\n");
    api_set_thread_policy(&attr, SCHED_RR);

    /* 还原之前的策略 */
    printf ("Restore current policy\n");
    api_set_thread_policy (&attr, policy);

    /* 
     * 反初始化 pthread_attr_t 结构
     * 如果 pthread_attr_init 的实现对属性对象的内存空间是动态分配的,
     * phread_attr_destory 就会释放该内存空间
     */
    rs = pthread_attr_destroy (&attr);
    assert (rs == 0);

    return 0;
}

线程互斥锁

#include <pthread.h> 
#include <stdio.h> 
#include <stdlib.h>
#include <malloc.h> 

typedef struct  
 { 
   double      *a; 
   double      *b; 
   double     sum;  
   int     veclen;  
 } DOTDATA; 

#define NUMTHRDS 4 
#define VECLEN 100 
   DOTDATA dotstr;  
   pthread_t callThd[NUMTHRDS]; 
   pthread_mutex_t mutexsum; 

void *dotprod(void *arg) 
{ 

   /* Define and use local variables for convenience */ 

   int i, start, end, offset, len ; 
   double mysum, *x, *y; 
   offset = (int)arg; 

   len = dotstr.veclen; 
   start = offset*len; 
   end   = start + len; 
   x = dotstr.a; 
   y = dotstr.b; 

   mysum = 0; 
   for (i=start; i<end ; i++)  
    { 
      mysum += (x[i] * y[i]); 
    } 

   pthread_mutex_lock (&mutexsum); 
   dotstr.sum += mysum; 
   pthread_mutex_unlock (&mutexsum); 

   pthread_exit((void*) 0); 
} 


int main (int argc, char *argv[]) 
{ 
   int i; 
   double *a, *b; 
   void *status; 
   pthread_attr_t attr; 

   a = (double*) malloc (NUMTHRDS*VECLEN*sizeof(double)); 
   b = (double*) malloc (NUMTHRDS*VECLEN*sizeof(double)); 

   for (i=0; i<VECLEN*NUMTHRDS; i++) 
    { 
     a[i]=1.0; 
     b[i]=a[i]; 
    } 

   dotstr.veclen = VECLEN;  
   dotstr.a = a;  
   dotstr.b = b;  
   dotstr.sum=0; 

   pthread_mutex_init(&mutexsum, NULL); 

   pthread_attr_init(&attr); 
   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 

        for(i=0; i<NUMTHRDS; i++) 
        { 
        pthread_create( &callThd[i], &attr, dotprod, (void *)i); 
        } 

        pthread_attr_destroy(&attr); 

        for(i=0; i<NUMTHRDS; i++) 
        { 
          pthread_join( callThd[i], &status); 
        } 

   printf ("Sum =  %f \n", dotstr.sum); 
   free (a); 
   free (b); 
   pthread_mutex_destroy(&mutexsum); 
   pthread_exit(NULL); 
} 

线程中使用条件变量

#include <pthread.h> 
#include <stdio.h> 
#include <stdlib.h>

#define NUM_THREADS  3 
#define TCOUNT 10 
#define COUNT_LIMIT 12 

int     count = 0; 
int     thread_ids[3] = {0,1,2}; 
pthread_mutex_t count_mutex; 
pthread_cond_t count_threshold_cv; 

void *inc_count(void *idp)  
{ 
  int j,i; 
  double result=0.0; 
  int *my_id = idp; 

  for (i=0; i<TCOUNT; i++) { 
    pthread_mutex_lock(&count_mutex); 
    count++; 

    if (count == COUNT_LIMIT) { 
      pthread_cond_signal(&count_threshold_cv); 
      printf("inc_count(): thread %d, count = %d  Threshold reached.\n", *my_id, count); 
      } 
    printf("inc_count(): thread %d, count = %d, unlocking mutex\n", *my_id, count); 
    pthread_mutex_unlock(&count_mutex); 

    for (j=0; j<1000; j++) 
      result = result + (double)random(); 
    } 
  pthread_exit(NULL); 
} 

void *watch_count(void *idp)  
{ 
  int *my_id = idp; 

  printf("Starting watch_count(): thread %d\n", *my_id); 

  pthread_mutex_lock(&count_mutex); 
  if (count<COUNT_LIMIT) { 
    pthread_cond_wait(&count_threshold_cv, &count_mutex); 
    printf("watch_count(): thread %d Condition signal received.\n", *my_id); 
    } 
  pthread_mutex_unlock(&count_mutex); 
  pthread_exit(NULL); 
} 

int main (int argc, char *argv[]) 
{ 
  int i, rc; 
  pthread_t threads[3]; 
  pthread_attr_t attr; 

  pthread_attr_init(&attr); 
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 
  pthread_create(&threads[0], &attr, inc_count, (void *)&thread_ids[0]); 
  pthread_create(&threads[1], &attr, inc_count, (void *)&thread_ids[1]); 
  pthread_create(&threads[2], &attr, watch_count, (void *)&thread_ids[2]); 

  for (i=0; i<NUM_THREADS; i++) { 
    pthread_join(threads[i], NULL); 
  } 
  printf ("Main(): Waited on %d  threads. Done.\n", NUM_THREADS); 

  pthread_attr_destroy(&attr); 
  pthread_mutex_destroy(&count_mutex); 
  pthread_cond_destroy(&count_threshold_cv); 
  pthread_exit(NULL); 

} 

设置线程栈

#include <pthread.h> 
#include <stdio.h> 
#include <stdlib.h>

#define NTHREADS 4 
#define N 1000 
#define MEGEXTRA 1000000 

pthread_attr_t attr; 

void *dowork(void *threadid) 
{ 
   double A[N][N]; 
   int i,j,tid; 
   size_t mystacksize; 

   tid = (int)threadid; 
   pthread_attr_getstacksize (&attr, &mystacksize); 
   printf("Thread %d: stack size = %li bytes \n", tid, mystacksize); 
   for (i=0; i<N; i++) 
     for (j=0; j<N; j++) 
      A[i][j] = ((i*j)/3.452) + (N-i); 
   pthread_exit(NULL); 
} 

int main(int argc, char *argv[]) 
{ 
   pthread_t threads[NTHREADS]; 
   size_t stacksize; 
   int rc, t; 

   pthread_attr_init(&attr); 
   pthread_attr_getstacksize (&attr, &stacksize); 
   printf("Default stack size = %li\n", stacksize); 
   stacksize = sizeof(double)*N*N+MEGEXTRA; 
   printf("Amount of stack needed per thread = %li\n",stacksize); 
   pthread_attr_setstacksize (&attr, stacksize); 
   printf("Creating threads with stack size = %li bytes\n",stacksize); 
   for(t=0; t<NTHREADS; t++){ 
      rc = pthread_create(&threads[t], &attr, dowork, (void *)t); 
      if (rc){ 
         printf("ERROR; return code from pthread_create() is %d\n", rc); 
         exit(-1); 
      } 
   } 
   printf("Created %d threads.\n", t); 
   pthread_exit(NULL); 
} 
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值