linux多线程示例

 1 #include <stdio.h>
 2 #include <unistd.h>
 3 #include <stdlib.h>
 4 #include <pthread.h>
 5
 6 typedef void* (*fun)(void*);
 7
 8 fun fun1, fun2;
 9
10 pthread_mutex_t pmu = PTHREAD_MUTEX_INITIALIZER;
11 pthread_cond_t cond;
12 pthread_t pid1, pid2;
13 int flag = 0;
14 int gnum = 0;
15 int gsub = 100;
16
17 void *  func1(void * para)
18 {
19     int k = (int)para;
20     printf("func1, ******\n");
21     while(gnum<=100)
22     {
23         pthread_mutex_lock(&pmu);
24         printf("gnum == %d", gnum);
25         while(gnum==50)
26         {
27             printf("suspend thread1 at gnum==50 !!! \n");
28             pthread_cond_wait(&cond, &pmu);
29             gnum++;
30        }
31         ++gnum;
32         ++flag;
33         ++k;
34         //printf("flag = %d, k = %d\n", flag, k);
35         pthread_mutex_unlock(&pmu);
36         printf("I am func1\n");
37     }
38             pthread_exit((void*)0);
39
40 }
41
42 void * func2(void * para)
43 {
44     int f = (int)para;
45     printf("f == %d\n", f);
46     printf("pthread2 start running !\n");
47     void * ret = NULL;
48     while(gsub>=0)
49     {
50         pthread_mutex_lock(&pmu);
51         gsub--;
52         printf("gsub= %d ", gsub);
53         if(gsub == 20)
54         {
55             printf("now gsnb ==20, and send signal\n");
56             pthread_cond_signal(&cond);
57         }
58         ++flag;
59        ++f;
60         printf("flag = %d, f = %d\n", flag, f);
61         pthread_mutex_unlock(&pmu);
62         printf("I am func2 \n");
63     }
64     //pthread_join(pid1, &ret);
65     pthread_exit((void*)0);
66 }
67
68 int main()
69 {
70     int id = 0;
71     void * ret = NULL;
72     int key = 5;
73
74     pthread_cond_init(&cond, NULL);  //属性设置NULL默认属性
75     id = pthread_create(&pid1, NULL, func1, (void*)key);
76     if(id != 0)
77     {
78         printf("pthread_create error !\n");
79         exit(0);
80     }
81
82     if(pthread_create(&pid2, NULL, func2, (void*)key))
83     {
84         printf("pthread_create error ! \n");
85         exit(0);
86     }
87     pthread_join(pid2, &ret);      //等待pid2线程退出
88     pthread_join(pid1, &ret);      //等待pid1线程退出

    //pthread_detach(pid1);        //主线程与pid1线程进行分离,一般用来实现异步返回    //pthread_detach(pid2);        //同上
89     pthread_exit((void*)0);
90 }

gcc test_thread.c -lpthread
./a.out

线程池实例代码:

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <unistd.h>
  4 #include <sys/types.h>
  5 #include <pthread.h>
  6 #include <assert.h>
  7
  8 typedef struct worker
  9 {
 10     //回调函数,任务运行时会调用此函数,也可以声明为其他形式;
 11     void * (*process)(void *arg);   //该函数返回值是任意类型的;参数也是任意类型的;`
 12     void *arg;  //回调函数的参数;
 13     struct worker *next;
 14 }CThread_worker;
 15
 16 //线程池结构
 17 typedef struct
 18 {
 19     pthread_mutex_t queue_lock;     //互斥量
 20     pthread_cond_t queue_ready;     //条件变量
 21
 22     //链表结构, 线程池中所有等待任务
 23     CThread_worker *queue_head;
 24
 25     //是否销毁线程池
 26     int shutdown;
 27     pthread_t *threadid;
 28
 29     //线程池中允许的活动线程数目;
 30     //线程池中允许的活动线程数目;
 31     int max_thread_num;
 32     //当前等待队列的任务数目;
 33     int  cur_queue_size;
 34
 35 }CThread_pool;
 36
 37 int pool_add_worker(void * (*process)(void *arg), void *arg);
 38 void * thread_routine(void *arg);
 39
 40 static CThread_pool *pool = NULL;
 41 void pool_init(int max_thread_num)
 42 {
 43     pool = (CThread_pool*)malloc(sizeof(CThread_pool));
 44
 45 //初始化互斥量;
 46     pthread_mutex_init(&(pool->queue_lock), NULL);
 47 //初始化条件变量
 48     pthread_cond_init(&(pool->queue_ready), NULL);
 49
 50     pool->queue_head = NULL;
 51
 52 //最大线程数目
 53     pool->max_thread_num = max_thread_num;
 54 //当前线程数目
 55     pool->cur_queue_size = 0;
 56
 57     pool->shutdown = 0;
 58     pool->threadid = (pthread_t*)malloc(max_thread_num * sizeof(pthread_t));
 59     int i = 0;
 60     for(i=0; i<max_thread_num;i++)
 61     {
 62         pthread_create(&(pool->threadid[i]), NULL, thread_routine, NULL);
 63     }
 64 }
 65
 66 //向线程池中加入任务
 67 int pool_add_worker(void*(*process)(void *arg), void *arg)
 68 {
 69     //构建一个新任务
 70     CThread_worker *newworker = (CThread_worker *)malloc(sizeof(CThread_worker));
 71     newworker->process = process;
 72     newworker->arg = arg;
 73     //别忘了置空
 74     newworker->next = NULL;
 75
 76 //加锁互斥量
 77     pthread_mutex_lock(&(pool->queue_lock));
 78     //将任务加入到等待队列中
 79     CThread_worker *member = pool->queue_head;
 80     if(member !=NULL)
 81     {
 82         while(member->next != NULL)
 83             member = member->next;
 84         member->next = newworker;
 85     }
 86     else
 87     {
 88         pool->queue_head = newworker;
 89     }
 90
 91     assert(pool->queue_head != NULL);
 92     pool->cur_queue_size++;
 93     pthread_mutex_unlock(&(pool->queue_lock));
 94
 95     //好了,等待队列中有任务了,唤醒一个等待线程;
 96     //     注意如果所有线程都在忙碌,这句没有任何作用
 97     pthread_cond_signal(&(pool->queue_ready));
 98     return 0;
 99 }
100
101 /*销毁线程池,等待队列中的任务不会再被执行,
102 *但是正在运行的线程会一直 把任务运行完后 再退出;
103 */
104
105 int pool_destroy()
106 {
107     if(pool->shutdown)
108         return -1;   //防止两次调用
109     pool->shutdown = 1;
110
111     //唤醒所有等待线程,线程池要销毁了
112     pthread_cond_broadcast(&(pool->queue_ready));
113
114     //阻塞等待线程退出, 否则就成僵尸了
115     int i;
116     for(i=0; i<pool->max_thread_num; i++)
117     {
118         pthread_join(pool->threadid[i], NULL);
119     }
120
121     free(pool->threadid);
122
123     //销毁等待队列
124     CThread_worker *head = NULL;
125     while(pool->queue_head != NULL)
126     {
127         head=pool->queue_head;
128         pool->queue_head = pool->queue_head->next;
129         free(head);
130     }
131
132     //条件变量和互斥量也别忘了销毁
133     pthread_mutex_destroy(&(pool->queue_lock));
134     pthread_cond_destroy(&(pool->queue_ready));
135
136     free(pool);
137      /*销毁后指针置空是个好习惯*/
138     pool = NULL;
139     return 0;
140 }
141
142 void* thread_routine(void *arg)
143 {
144                    printf("start thread 0x%x\n", pthread_self());
145     while(1)
146     {
147         pthread_mutex_lock(&(pool->queue_lock));
148 /*如果等待队列为0并且不销毁线程池,则处于阻塞状态; 注意
149  *pthread_cond_wait是一个原子操作,等待前会解锁,唤醒后会加锁*/
150         while(pool->cur_queue_size == 0 && !pool->shutdown)
151         {
152             printf("thread 0x%x is waiting \n", pthread_self());
153             pthread_cond_wait(&(pool->queue_ready), &(pool->queue_lock));
154         }
155
156         //线程池要销毁了;
157         if(pool->shutdown)
158         {
159             //遇到break,continue,return等跳转语句,千万不要忘记先解锁*/
160             pthread_mutex_unlock(&(pool->queue_lock));
161             printf("thread 0x %x will exit \n", pthread_self());
162             pthread_exit(NULL);
163         }
164
165         printf("thread 0x %x is starting to work \n", pthread_self());
166
167         //使用断言
168         assert(pool->cur_queue_size!= 0);
169         assert(pool->queue_head!= NULL);
170
171         //等待队列长度减去1,并取出链表中的头元素
172         pool->cur_queue_size--;
173        CThread_worker *worker = pool->queue_head;
174         pool->queue_head = worker->next;
175         pthread_mutex_unlock(&(pool->queue_lock));
176
177         //调用回调函数,执行任务
178         (*(worker->process))(worker->arg);
179         free(worker);
180         worker = NULL;
181     }
182     //这一句正常情况下是不可达的
183     pthread_exit(NULL);
184 }
185
186 //test code
187 void *myprocess(void *arg)
188 {
189     printf("threadid is 0x%x, working on task %d\n", pthread_self(), *(int*)arg);
190     sleep(1);  //休息一秒,延长任务的执行时间
191     return NULL;
192 }
193
194 int main(int argc, char** argv)
195 {
196     pool_init(3); /*线程池中最多三个活动线程*/
197
198     //连续向线程池中放入10个任务;
199     int *workingnum = (int*)malloc(sizeof(int)*10);
200     int i;
201     for(i=0; i< 10;i++)
202     {
203         workingnum[i] = i;
204         pool_add_worker(myprocess, &workingnum[i]);
205     }
206
207     sleep(5);
208 //销毁线程池;
209     pool_destroy();
210     free(workingnum);
211
212     return 0;
213 }

 

时间: 2025-01-01 06:48:06

linux多线程示例的相关文章

Linux多线程之同步

引言 条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待条件变量的条件成立而挂起(此时不再占用cpu):另一个线程使条件成立(给出条件成立信号).为了防止竞争,条件变量的使用总是和一个互斥锁结合在一起. 函数原型 1. 定义条件变量 #include <pthread.h>/* 定义两个条件变量 */pthread_cond_t cond_pro, cond_con; 2. 初始化和销毁条件变量 #include <pthread.h>int pt

Linux多线程的实现代码

#include <pthread.h>#include <stdio.h>#include <sys/time.h>#include <string.h>#define MAX 10pthread_t thread[2];pthread_mutex_t mut;int number=0, i;void *thread1(){ printf ("thread1 : I'm thread 1\n"); for (i = 0; i <

linux多线程编程详解教程

 这篇文章主要介绍了linux多线程编程详解教程,提供线程通过信号量实现通信的代码,大家参考使用吧 线程分类   线程按照其调度者可以分为用户级线程和核心级线程两种.   (1)用户级线程  用户级线程主要解决的是上下文切换的问题,它的调度算法和调度过程全部由用户自行选择决定,在运行时不需要特定的内核支持.在这里,操作系统往往会提供一个用户空间的线程库,该线程库提供了线程的创建.调度.撤销等功能,而内核仍然仅对进程进行管理.如果一个进程中的某一个线程调用了一个阻塞的系统调用,那么该进程包括该进程

select-ARM9 + Linux多线程精确的定时器

问题描述 ARM9 + Linux多线程精确的定时器 最近公司有个项目平台是ARM9 + linux, 在开发过程中遇到一个问题: 有一部分CAN通讯,需要250ms定时发送一帧数据包.于是我用select做了一个定时器发送.但是当这个多线程的程序真正跑起来,在接受端进行检测.结果收到的该帧的时间间隔竟然是330ms左右.虽然预先我知道有偏差,但是330的时间间隔确实大大超出了预期!如果用setitimer的话,一是资源少,二是信号如果加入程序中,可能会带来很多不必要的BUG.哪位大神有更好的定

Linux多线程编程小结

前一段时间由于开题的事情一直耽搁了我搞Linux的进度,搞的我之前学的东西都遗忘了,非常烦躁的说,如今抽个时间把之前所学的做个小节.文章内容主要总结于<Linux程序设计第3版>. 1.Linux进程与线程 Linux进程创建一个新线程时,线程将拥有自己的栈(由于线程有自己的局部变量),但与它的创建者共享全局变量.文件描写叙述符.信号句柄和当前文件夹状态. Linux通过fork创建子进程与创建线程之间是有差别的:fork创建出该进程的一份拷贝,这个新进程拥有自己的变量和自己的PID,它的时间

linux多线程编程中如何等待过个线程退出

问题描述 linux多线程编程中如何等待过个线程退出 linux多线程编程中,如果线程A创建了线程B,我知道用pthread__ join可以令线程A 阻塞然后等待线程B的退出.如果线程A创建了三个线程B,C,D,执行完的先后顺序不知.想让A必须等待三个线程都退出后再退出,应该怎么做? 连用pthread__join三次吗???但是第一次用了pthread__join后,A不就阻塞了吗? 解决方案 多线程编程(一):线程创建和退出Linux多线程编程(创建线程)Linux多线程编程(创建线程)

Linux多线程使用互斥量同步线程_Linux

本文将会给出互斥量的详细解说,并用一个互斥量解决上一篇文章中,要使用两个信号量才能解决的只有子线程结束了对输入的处理和统计后,主线程才能继续执行的问题. 一.什么是互斥量 互斥量是另一种用于多线程中的同步访问方法,它允许程序锁住某个对象,使得每次只能有一个线程访问它.为了控制对关键代码的访问,必须在进入这段代码之前锁住一个互斥量,然后在完成操作之后解锁. 二.互斥量的函数的使用 它们的定义与使用信号量的函数非常相似,它们的定义如下: #include <pthread.h> int pthre

详解Linux多线程使用信号量同步_Linux

信号量.同步这些名词在进程间通信时就已经说过,在这里它们的意思是相同的,只不过是同步的对象不同而已.但是下面介绍的信号量的接口是用于线程的信号量,注意不要跟用于进程间通信的信号量混淆. 一.什么是信号量 线程的信号量与进程间通信中使用的信号量的概念是一样,它是一种特殊的变量,它可以被增加或减少,但对其的关键访问被保证是原子操作.如果一个程序中有多个线程试图改变一个信号量的值,系统将保证所有的操作都将依次进行. 而只有0和1两种取值的信号量叫做二进制信号量,在这里将重点介绍.而信号量一般常用于保护

Linux多线程编程(一)_Linux

一.什么是线程?       线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源. 二.什么时候使用多线程?     当多个任务可以并行执行时,可以为每个任务启动一个线程. 三.线程的创建     使用pthread_create函数.     #include<pthread.h> int pthre