Linux多线程编程实例 [转→改]

2356阅读 0评论2011-11-23 bo_00
分类:LINUX

原地址:http://blog.csdn.net/tody_guo/article/details/5984367

对原帖稍微改了一些小地方。

  1. /*********
  2. 多线程编程
  3. **********/
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <pthread.h>

  7. void *mythread2()
  8. {
  9.     int i;
  10.     for(i=0;i<3;i++)
  11.         printf("This is a pthread 2:\n");
  12.     pthread_exit("pthread 2 Thank you for the CPU time\n");
  13. }
  14. void *mythread1()
  15. {
  16.     int i;
  17.     for(i=0;i<3;i++)
  18.         printf("This is a pthread 1:\n");
  19.     pthread_exit("pthread 1 Thank you for the CPU time\n");
  20. }
  21. int main(int argc,char **argv)
  22. {
  23.     pthread_t id1,id2;
  24.     int i, ret;
  25.     void *thread_result;
  26.     ret = pthread_create(&id2,NULL,mythread2,NULL);
  27.     if(ret!=0)
  28.     {
  29.          printf("Create pthread 2 failed\n");
  30.         exit(0);
  31.     }
  32.     ret = pthread_create(&id1,NULL,mythread1,NULL);
  33.     if(ret!=0)
  34.     {
  35.          printf("Create pthread 1 failed\n");
  36.         exit(0);
  37.     }
  38.     
  39.     for(i=0;i<3;i++)
  40.         printf("This is the main process:\n");
  41.     pthread_join(id1,&thread_result);
  42.     printf("Thread1 joined,it returned:%s",(char *)thread_result);
  43.     pthread_join(id2,&thread_result);
  44.     printf("Thread2 joined,it returned:%s",(char *)thread_result);
  45.     return 0;
  46. }
  47. /* 打印输出结果 */
  48. /* This is the main process: */
  49. /* This is the main process: */
  50. /* This is the main process: */
  51. /* This is a pthread 1: */
  52. /* This is a pthread 1: */
  53. /* This is a pthread 1: */
  54. /* Thread1 joined,it returned:pthread 1 Thank you for the CPU time */
  55. /* This is a pthread 2: */
  56. /* This is a pthread 2: */
  57. /* This is a pthread 2: */
  58. /* Thread2 joined,it returned:pthread 2 Thank you for the CPU time */

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <pthread.h>
  4. #include <unistd.h>

  5. void *mythread2()
  6. {
  7.     int i;
  8.     for(i=0;i<3;i++)
  9.     {
  10.         printf("This is a pthread 2:\n");
  11.         sleep(1);
  12.     }
  13.     pthread_exit("pthread 2 Thank you for the CPU time\n");
  14. }
  15. void *mythread1()
  16. {
  17.     int i;
  18.     for(i=0;i<3;i++)
  19.     {
  20.         printf("This is a pthread 1:\n");
  21.         sleep(1);
  22.     }
  23.     pthread_exit("pthread 1 Thank you for the CPU time\n");
  24. }
  25. int main()
  26. {
  27.     pthread_t     id1,id2;
  28.     int         i, ret;
  29.     void        *thread_result;
  30.     ret = pthread_create(&id2,NULL,mythread2,NULL);
  31.     if(ret!=0)
  32.     {
  33.         printf("Create pthread 2 failed\n");
  34.         exit(0);
  35.     }
  36.     ret = pthread_create(&id1,NULL,mythread1,NULL);
  37.     if(ret!=0)
  38.     {
  39.         printf("Create pthread 1 failed");
  40.         exit(0);
  41.     }
  42.     for(i=0;i<3;i++)
  43.     {
  44.         printf("This is the main process:\n");
  45.         sleep(1);
  46.     }
  47.     pthread_join(id1,&thread_result);
  48.     printf("Thread1 joined,it returned:%s",(char *)thread_result);
  49.     pthread_join(id2,&thread_result);
  50.     printf("Thread2 joined,it returned:%s",(char *)thread_result);
  51.     return 0;
  52. }
  53. /* 打印输出结果 */
  54. /* This is the main process: */
  55. /* This is a pthread 1: */
  56. /* This is a pthread 2: */
  57. /* This is the main process: */
  58. /* This is a pthread 1: */
  59. /* This is a pthread 2: */
  60. /* This is the main process: */
  61. /* This is a pthread 1: */
  62. /* This is a pthread 2: */
  63. /* Thread1 joined,it returned:pthread 1 Thank you for the CPU time */
  64. /* Thread2 joined,it returned:pthread 2 Thank you for the CPU time */

  1. /*********
  2. 取消线程
  3. **********/

  4. #include <pthread.h>
  5. #include <stdio.h>
  6. #include <errno.h>
  7. #include <stdlib.h>
  8. #include <unistd.h>

  9. #define handle_error_en(en, msg) \
  10.         do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)

  11. static void *
  12. thread_func(void *ignored_argument)
  13. {
  14.     int s;

  15.    /* Disable cancellation for a while, so that we don't
  16.        immediately react to a cancellation request */

  17.    s = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
  18.     if (s != 0)
  19.         handle_error_en(s, "pthread_setcancelstate");

  20.    printf("thread_func(): started; cancellation disabled\n");
  21.     sleep(5);
  22.     printf("thread_func(): about to enable cancellation\n");

  23.    s = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
  24.     if (s != 0)
  25.         handle_error_en(s, "pthread_setcancelstate");

  26.    /* sleep() is a cancellation point */

  27.    sleep(1000); /* Should get canceled while we sleep */

  28.    /* Should never get here */

  29.    printf("thread_func(): not canceled!\n");
  30.     return NULL;
  31. }

  32. int
  33. main(void)
  34. {
  35.     pthread_t thr;
  36.     void *res;
  37.     int s;

  38.    /* Start a thread and then send it a cancellation request */

  39.    s = pthread_create(&thr, NULL, &thread_func, NULL);
  40.     if (s != 0)
  41.         handle_error_en(s, "pthread_create");

  42.    sleep(2); /* Give thread a chance to get started */

  43.    printf("main(): sending cancellation request\n");
  44.     s = pthread_cancel(thr);
  45.     if (s != 0)
  46.         handle_error_en(s, "pthread_cancel");

  47.    /* Join with thread to see what its exit status was */

  48.    s = pthread_join(thr, &res);
  49.     if (s != 0)
  50.         handle_error_en(s, "pthread_join");

  51.    if (res == PTHREAD_CANCELED//目标线程被取消,PTHREAD_CANCELED会被放置在*res中
  52.         printf("main(): thread was canceled\n");
  53.     else
  54.         printf("main(): thread wasn't canceled (shouldn't happen!)\n");
  55.     exit(EXIT_SUCCESS);
  56. }


  1. /*********
  2. 线程属性
  3. **********/
  4. #define _GNU_SOURCE /* 引入 pthread_getattr_np() 声明 */
  5. #include <pthread.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <unistd.h>
  9. #include <errno.h>

  10. #define handle_error_en(en, msg) \
  11.         do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)

  12. static void
  13. display_pthread_attr(pthread_attr_t *attr, char *prefix)
  14. {
  15.     int s, i;
  16.     size_t v;
  17.     void *stkaddr;
  18.     struct sched_param sp;

  19.     s = pthread_attr_getdetachstate(attr, &i);//获取线程属性对象的分离状态属性
  20.     if (s != 0)
  21.         handle_error_en(s, "pthread_attr_getdetachstate");
  22.     printf("%sDetach state = %s\n", prefix,
  23.         (i == PTHREAD_CREATE_DETACHED) ? "PTHREAD_CREATE_DETACHED" :
  24.         (i == PTHREAD_CREATE_JOINABLE) ? "PTHREAD_CREATE_JOINABLE" :
  25.         "???");

  26.     s = pthread_attr_getscope(attr, &i);//获取线程属性对象里的竞争作用域属性
  27.     if (s != 0)
  28.         handle_error_en(s, "pthread_attr_getscope");
  29.     printf("%sScope = %s\n", prefix,
  30.         (i == PTHREAD_SCOPE_SYSTEM) ? "PTHREAD_SCOPE_SYSTEM" :
  31.         (i == PTHREAD_SCOPE_PROCESS) ? "PTHREAD_SCOPE_PROCESS" :
  32.         "???");

  33.     s = pthread_attr_getinheritschedw(attr, &i);//获取 线程属性对象里的继承调度属性
  34.     if (s != 0)
  35.         handle_error_en(s, "pthread_attr_getinheritsched");
  36.     printf("%sInherit scheduler = %s\n", prefix,
  37.         (i == PTHREAD_INHERIT_SCHED) ? "PTHREAD_INHERIT_SCHED" :
  38.         (i == PTHREAD_EXPLICIT_SCHED) ? "PTHREAD_EXPLICIT_SCHED" :
  39.         "???");

  40.     s = pthread_attr_getschedpolicy(attr, &i);//获取线程属性对象的调度策略属性
  41.     if (s != 0)
  42.     handle_error_en(s, "pthread_attr_getschedpolicy");
  43.     printf("%sScheduling policy = %s\n", prefix,
  44.         (i == SCHED_OTHER) ? "SCHED_OTHER" :
  45.         (i == SCHED_FIFO) ? "SCHED_FIFO" :
  46.         (i == SCHED_RR) ? "SCHED_RR" :
  47.         "???");

  48.     s = pthread_attr_getschedparam(attr, &sp);//获取在线程属性对象里的调度参数属性
  49.     if (s != 0)
  50.         handle_error_en(s, "pthread_attr_getschedparam");
  51.     printf("%sScheduling priority = %d\n", prefix, sp.sched_priority);

  52.     s = pthread_attr_getguardsize(attr, &v);//获取 线程属性对象里预留空间尺寸
  53.     if (s != 0)
  54.         handle_error_en(s, "pthread_attr_getguardsize");
  55.     printf("%sGuard size = %d bytes\n", prefix, v);

  56.     s = pthread_attr_getstack(attr, &stkaddr, &v);//获取线程属性对象里的栈属性
  57.     if (s != 0)
  58.         handle_error_en(s, "pthread_attr_getstack");
  59.     printf("%sStack address = %p\n", prefix, stkaddr);
  60.     printf("%sStack size = 0x%x bytes\n", prefix, v);
  61. }

  62. static void *
  63. thread_start(void *arg)
  64. {
  65.     int s;
  66.     pthread_attr_t gattr;

  67.     /* pthread_getattr_np() 一个非标准的 GNU 扩展,
  68.         它用于取得其第一个参数引用的线程的属性。*/

  69.     s = pthread_getattr_np(pthread_self(), &gattr);//pthread_self()获得calling线程的线程id
  70.     if (s != 0)
  71.         handle_error_en(s, "pthread_getattr_np");

  72.     printf("Thread attributes:\n");
  73.     display_pthread_attr(&gattr, "\t");

  74.     exit(EXIT_SUCCESS); /* 终止所有线程 */
  75. }

  76. int
  77. main(int argc, char *argv[])
  78. {
  79.     pthread_t thr;
  80.     pthread_attr_t attr;
  81.     pthread_attr_t *attrp; /* NULL or &attr */
  82.     int s;

  83.     attrp = NULL;

  84.     /* 如果命令行参数提供了,使用它来设置线尺寸属性,
  85.      以及一些其它属性,并设置 attrp 指向这个线程属性对象 */

  86.     printf("argc=%d\n",argc);
  87.     
  88.     if (argc > 1) {
  89.         int        stack_size;
  90.         void *sp;

  91.         attrp = &attr;

  92.         s = pthread_attr_init(&attr);
  93.         if (s != 0)
  94.             handle_error_en(s, "pthread_attr_init");

  95.         s = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  96.         if (s != 0)
  97.             handle_error_en(s, "pthread_attr_setdetachstate");

  98.         s = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
  99.         if (s != 0)
  100.             handle_error_en(s, "pthread_attr_setinheritsched");

  101.         stack_size = strtoul(argv[1], NULL, 0);//convert a string to an unsigned long integer

  102.         s = posix_memalign(&sp, sysconf(_SC_PAGESIZE), stack_size);//对齐内存分配
  103.         if (s != 0)
  104.             handle_error_en(s, "posix_memalign");

  105.         printf("posix_memalign() allocated at %p\n", sp);

  106.         s = pthread_attr_setstack(&attr, sp, stack_size);//设置线程属性对象里的栈属性(地址/尺寸)
  107.         if (s != 0)
  108.             handle_error_en(s, "pthread_attr_setstack");
  109. }

  110.     s = pthread_create(&thr, attrp, &thread_start, NULL);
  111.     if (s != 0)
  112.         handle_error_en(s, "pthread_create");

  113.     if (attrp != NULL) {
  114.         s = pthread_attr_destroy(attrp);
  115.         if (s != 0)
  116.             handle_error_en(s, "pthread_attr_destroy");
  117.     }

  118.     pause();                    /* 当其它线程调用 exit() 时终止 */
  119.     return 0;
  120. }


//pthread_attr_init()的man手册实例
//$ ./a.out
//$ ./a.out 0x3000000


  1. /*********
  2. 线程互斥量
  3. **********/
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <unistd.h>
  7. #include <pthread.h>

  8. int x;
  9. pthread_mutex_t mutex; // 声明一个互斥量
  10.    
  11. void thread1(void)
  12. {
  13.     while(x>0)
  14.     {
  15.         pthread_mutex_lock(&mutex); //上锁
  16.         printf("Thread 1 is running x=%d\n",x);
  17.         x--;
  18.         pthread_mutex_unlock(&mutex); //解锁
  19.         sleep(1);
  20.     }
  21.     pthread_exit(NULL);
  22. }
  23.    
  24. void thread2(void)
  25. {
  26.     while(x>0)
  27.     {
  28.         pthread_mutex_lock(&mutex);    //上锁 //注释本行看区别
  29.         sleep(3);
  30.         printf("Thread 2 is running x=%d\n",x);
  31.         x--;
  32.         pthread_mutex_unlock(&mutex); //解锁
  33.         sleep(1);
  34.     }
  35.     pthread_exit(NULL);
  36. }
  37.    
  38. int main()
  39. {
  40.     pthread_t id1,id2;
  41.     int ret;
  42.     ret = pthread_mutex_init(&mutex,NULL); //初始化互斥量
  43.     if(ret!=0)
  44.     {
  45.         printf("pthread_mutex_init error\n");
  46.         exit(0);
  47.     }
  48.     x=10; //初始值
  49.     ret = pthread_create(&id1,NULL,(void *)thread1,NULL); //创建线程1
  50.     if(ret!=0)
  51.     {
  52.         printf("Create pthread 1 error\n");
  53.         exit(0);
  54.     }
  55.     ret = pthread_create(&id2,NULL,(void *)thread2,NULL); //创建线程2
  56.     if(ret!=0)
  57.     {
  58.         printf("Create pthread 2 error\n");
  59.         exit(0);
  60.     }
  61.     pthread_join(id1,NULL); //线程结束聚合线程
  62.     pthread_join(id2,NULL);
  63.     printf("Done\n");
  64.     return 0;
  65. }

  1. /*********
  2. 线程条件
  3. **********/
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <pthread.h>
  7. #include <unistd.h>

  8. int x;
  9. pthread_mutex_t mutex;
  10. pthread_cond_t cond;
  11.    
  12. void producer(void)
  13. {
  14.     while(1)
  15.     {
  16.         pthread_mutex_lock(&mutex);
  17.         int i;
  18.         for(i=0;i<3-x;i++)
  19.         {
  20.             x++;
  21.             printf("Producing:i=%d x=%d \n",i,x);
  22.             sleep(1);
  23.         }
  24.         if(x>=3)
  25.         {
  26.             pthread_cond_signal(&cond);    /*条件改变,发送信号,通知consumer线程,激活等待该条件的线程*/
  27.             /*pthread_cond_broadcast()激活所有等待线程*/
  28.             printf("Producing complete %d\n",x);
  29.         }
  30.         pthread_mutex_unlock(&mutex);
  31.         printf("producer Unlock Mutex\n");
  32.         sleep(1);
  33.     }
  34.     pthread_exit(NULL);
  35. }
  36.    
  37. void consumer(void)
  38. {
  39.     while(1)
  40.     {
  41.         pthread_mutex_lock(&mutex);
  42.         while(x<3)
  43.         {
  44.             pthread_cond_wait(&cond,&mutex);//等待一个条件 //等待
  45.             printf("start consuming %d\n",x);
  46.         }
  47.         if(x>0)
  48.         {
  49.             x--;
  50.             printf(" consuming %d\n",x);
  51.             sleep(1);
  52.         }
  53.         pthread_mutex_unlock(&mutex);
  54.         printf("consumer Unlock Mutex\n");
  55.     }
  56.     pthread_exit(NULL);
  57. }
  58.    
  59. int main()
  60. {
  61.     pthread_t id1,id2;
  62.     int ret;
  63.     ret = pthread_mutex_init(&mutex,NULL); //初始化互斥量
  64.     if(ret!=0)
  65.     {
  66.         printf("pthread_mutex_init error\n");
  67.         exit(0);
  68.     }
  69.     ret=pthread_cond_init(&cond,NULL); //初始化条件变量
  70.     if(ret!=0)
  71.     {
  72.         printf("pthread_cond_init error\n");
  73.         exit(0);
  74.     }
  75.     printf("x=[%d]\n",x);
  76.     ret = pthread_create(&id1,NULL,(void *)producer,NULL); //创建线程1 发生器
  77.     if(ret!=0)
  78.     {
  79.         printf("Create pthread producer error\n");
  80.         exit(0);
  81.     }
  82.     ret = pthread_create(&id2,NULL,(void *)consumer,NULL); //创建线程2 消耗器
  83.     if(ret!=0)
  84.     {
  85.         printf("Create pthread consumer, error\n");
  86.         exit(0);
  87.     }
  88.     pthread_join(id1,NULL);
  89.     pthread_join(id2,NULL);
  90.     printf("Done\n");
  91.     return 0;
  92. }


  1. /*********
  2. 线程条件 信号量
  3. **********/

  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <pthread.h>
  8. #include <semaphore.h>

  9. sem_t sem;
  10. char buffer[256];
  11.    
  12. void mythread(void)
  13. {
  14.     sem_wait(&sem); //递减锁定一个信号量
  15.     while(strncmp("exit",buffer,4))
  16.     {
  17.         printf("You input %d characters\n",strlen(buffer)-1);
  18.         sem_wait(&sem);
  19.     }
  20.     pthread_exit(NULL);
  21. }
  22. int main()
  23. {
  24.     pthread_t id;
  25.     int ret;
  26.     ret=sem_init(&sem,0,0); //初始化一个匿名信号量,进程内线程共享,
  27.     if(ret!=0)
  28.     {
  29.         printf("Semaphare initialization failed\n");
  30.         exit(1);
  31.     }
  32.     ret=pthread_create(&id,NULL,(void *)&mythread,NULL); //创建线程
  33.         if(ret!=0)
  34.         {
  35.             printf("pthread_create failed\n");
  36.             exit(1);
  37.         }
  38.     printf("Input some text,Enter'.'to finish\n");
  39.     while(strncmp("exit",buffer,4)!=0)
  40.     {
  41.         fgets(buffer,256,stdin);        //FILE *stdin standard I/O streams
  42.         sem_post(&sem);            //增加解锁一个信号量
  43.     }
  44.     pthread_join(id,NULL);
  45.     printf("Thtead joined,\n");
  46.     sem_destroy(&sem);
  47.     return 0;
  48. }






















上一篇:man手册的manpath $MANPATH
下一篇:动态数组