linux多线程示例
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h> typedef void* (*fun)(void*); fun fun1, fun2; pthread_mutex_t pmu = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond;
pthread_t pid1, pid2;
int flag = ;
int gnum = ;
int gsub = ; void * func1(void * para)
{
int k = (int)para;
printf("func1, ******\n");
while(gnum<=)
{
pthread_mutex_lock(&pmu);
printf("gnum == %d", gnum);
while(gnum==)
{
printf("suspend thread1 at gnum==50 !!! \n");
pthread_cond_wait(&cond, &pmu);
gnum++;
}
++gnum;
++flag;
++k;
//printf("flag = %d, k = %d\n", flag, k);
pthread_mutex_unlock(&pmu);
printf("I am func1\n");
}
pthread_exit((void*)); } void * func2(void * para)
{
int f = (int)para;
printf("f == %d\n", f);
printf("pthread2 start running !\n");
void * ret = NULL;
while(gsub>=)
{
pthread_mutex_lock(&pmu);
gsub--;
printf("gsub= %d ", gsub);
if(gsub == )
{
printf("now gsnb ==20, and send signal\n");
pthread_cond_signal(&cond);
}
++flag;
++f;
printf("flag = %d, f = %d\n", flag, f);
pthread_mutex_unlock(&pmu);
printf("I am func2 \n");
}
//pthread_join(pid1, &ret);
pthread_exit((void*));
} int main()
{
int id = ;
void * ret = NULL;
int key = ; pthread_cond_init(&cond, NULL); //属性设置NULL默认属性
id = pthread_create(&pid1, NULL, func1, (void*)key);
if(id != )
{
printf("pthread_create error !\n");
exit();
} if(pthread_create(&pid2, NULL, func2, (void*)key))
{
printf("pthread_create error ! \n");
exit();
}
87 pthread_join(pid2, &ret); //等待pid2线程退出
88 pthread_join(pid1, &ret); //等待pid1线程退出 //pthread_detach(pid1); //主线程与pid1线程进行分离,一般用来实现异步返回
//pthread_detach(pid2); //同上
pthread_exit((void*));
}
gcc test_thread.c -lpthread
./a.out
线程池实例代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <pthread.h>
#include <assert.h> typedef struct worker
{
//回调函数,任务运行时会调用此函数,也可以声明为其他形式;
void * (*process)(void *arg); //该函数返回值是任意类型的;参数也是任意类型的;`
void *arg; //回调函数的参数;
struct worker *next;
}CThread_worker; //线程池结构
typedef struct
{
pthread_mutex_t queue_lock; //互斥量
pthread_cond_t queue_ready; //条件变量 //链表结构, 线程池中所有等待任务
CThread_worker *queue_head; //是否销毁线程池
int shutdown;
pthread_t *threadid; //线程池中允许的活动线程数目;
//线程池中允许的活动线程数目;
int max_thread_num;
//当前等待队列的任务数目;
int cur_queue_size; }CThread_pool; int pool_add_worker(void * (*process)(void *arg), void *arg);
void * thread_routine(void *arg); static CThread_pool *pool = NULL;
void pool_init(int max_thread_num)
{
pool = (CThread_pool*)malloc(sizeof(CThread_pool)); //初始化互斥量;
pthread_mutex_init(&(pool->queue_lock), NULL);
//初始化条件变量
pthread_cond_init(&(pool->queue_ready), NULL); pool->queue_head = NULL; //最大线程数目
pool->max_thread_num = max_thread_num;
//当前线程数目
pool->cur_queue_size = ; pool->shutdown = ;
pool->threadid = (pthread_t*)malloc(max_thread_num * sizeof(pthread_t));
int i = ;
for(i=; i<max_thread_num;i++)
{
pthread_create(&(pool->threadid[i]), NULL, thread_routine, NULL);
}
} //向线程池中加入任务
int pool_add_worker(void*(*process)(void *arg), void *arg)
{
//构建一个新任务
CThread_worker *newworker = (CThread_worker *)malloc(sizeof(CThread_worker));
newworker->process = process;
newworker->arg = arg;
//别忘了置空
newworker->next = NULL; //加锁互斥量
pthread_mutex_lock(&(pool->queue_lock));
//将任务加入到等待队列中
CThread_worker *member = pool->queue_head;
if(member !=NULL)
{
while(member->next != NULL)
member = member->next;
member->next = newworker;
}
else
{
pool->queue_head = newworker;
} assert(pool->queue_head != NULL);
pool->cur_queue_size++;
pthread_mutex_unlock(&(pool->queue_lock)); //好了,等待队列中有任务了,唤醒一个等待线程;
// 注意如果所有线程都在忙碌,这句没有任何作用
pthread_cond_signal(&(pool->queue_ready));
return ;
} /*销毁线程池,等待队列中的任务不会再被执行,
*但是正在运行的线程会一直 把任务运行完后 再退出;
*/ int pool_destroy()
{
if(pool->shutdown)
return -; //防止两次调用
pool->shutdown = ; //唤醒所有等待线程,线程池要销毁了
pthread_cond_broadcast(&(pool->queue_ready)); //阻塞等待线程退出, 否则就成僵尸了
int i;
for(i=; i<pool->max_thread_num; i++)
{
pthread_join(pool->threadid[i], NULL);
} free(pool->threadid); //销毁等待队列
CThread_worker *head = NULL;
while(pool->queue_head != NULL)
{
head=pool->queue_head;
pool->queue_head = pool->queue_head->next;
free(head);
} //条件变量和互斥量也别忘了销毁
pthread_mutex_destroy(&(pool->queue_lock));
pthread_cond_destroy(&(pool->queue_ready)); free(pool);
/*销毁后指针置空是个好习惯*/
pool = NULL;
return ;
} void* thread_routine(void *arg)
{
printf("start thread 0x%x\n", pthread_self());
while()
{
pthread_mutex_lock(&(pool->queue_lock));
/*如果等待队列为0并且不销毁线程池,则处于阻塞状态; 注意
*pthread_cond_wait是一个原子操作,等待前会解锁,唤醒后会加锁*/
while(pool->cur_queue_size == && !pool->shutdown)
{
printf("thread 0x%x is waiting \n", pthread_self());
pthread_cond_wait(&(pool->queue_ready), &(pool->queue_lock));
} //线程池要销毁了;
if(pool->shutdown)
{
//遇到break,continue,return等跳转语句,千万不要忘记先解锁*/
pthread_mutex_unlock(&(pool->queue_lock));
printf("thread 0x %x will exit \n", pthread_self());
pthread_exit(NULL);
} printf("thread 0x %x is starting to work \n", pthread_self()); //使用断言
assert(pool->cur_queue_size!= );
assert(pool->queue_head!= NULL); //等待队列长度减去1,并取出链表中的头元素
pool->cur_queue_size--;
CThread_worker *worker = pool->queue_head;
pool->queue_head = worker->next;
pthread_mutex_unlock(&(pool->queue_lock)); //调用回调函数,执行任务
(*(worker->process))(worker->arg);
free(worker);
worker = NULL;
}
//这一句正常情况下是不可达的
pthread_exit(NULL);
} //test code
void *myprocess(void *arg)
{
printf("threadid is 0x%x, working on task %d\n", pthread_self(), *(int*)arg);
sleep(); //休息一秒,延长任务的执行时间
return NULL;
} int main(int argc, char** argv)
{
pool_init(); /*线程池中最多三个活动线程*/ //连续向线程池中放入10个任务;
int *workingnum = (int*)malloc(sizeof(int)*);
int i;
for(i=; i< ;i++)
{
workingnum[i] = i;
pool_add_worker(myprocess, &workingnum[i]);
} sleep();
//销毁线程池;
pool_destroy();
free(workingnum); return ;
}
linux多线程示例的更多相关文章
- 《Linux多线程服务端编程:使用muduo C++网络库》上市半年重印两次,总印数达到了9000册
<Linux多线程服务端编程:使用muduo C++网络库>这本书自今年一月上市以来,半年之内已经重印两次(加上首印,一共是三次印刷),总印数达到了9000册,这在技术书里已经算是相当不错 ...
- Linux 多线程应用中如何编写安全的信号处理函数
http://blog.163.com/he_junwei/blog/static/1979376462014021105242552/ http://www.ibm.com/developerwor ...
- LINUX多线程(一)(创建和退出)
1. Linux多线程概述 1.1. 概述 进程是系统中程序执行和资源分配的基本单位.每个进程有自己的数据段.代码段和堆栈段.这就造成进程在进行切换等操作时都需要有比较负责的上下文切换等动作.为了进一 ...
- 笔记整理--Linux多线程
Unix高级环境编程系列笔记 (2013/11/17 14:26:38) Unix高级环境编程系列笔记 出处信息 通过这篇文字,您将能够解答如下问题: 如何来标识一个线程? 如何创建一个新线程? 如何 ...
- Linux多线程编程初探
Linux线程介绍 进程与线程 典型的UNIX/Linux进程可以看成只有一个控制线程:一个进程在同一时刻只做一件事情.有了多个控制线程后,在程序设计时可以把进程设计成在同一时刻做不止一件事,每个线程 ...
- Linux 多线程 - 线程异步与同步机制
Linux 多线程 - 线程异步与同步机制 I. 同步机制 线程间的同步机制主要包括三个: 互斥锁:以排他的方式,防止共享资源被并发访问:互斥锁为二元变量, 状态为0-开锁.1-上锁;开锁必须由上锁的 ...
- ZT 为什么pthread_cond_t要和pthread_mutex_t同时使用 || pthread/Linux多线程编程
为什么线程同步的时候pthread_cond_t要和pthread_mutex_t同时使用 (2009-10-27 11:07:23) 转载▼ 标签: 杂谈 分类: 计算机 举一个例子(http:// ...
- Linux 多线程应用中如何编写安全的信号处理函数【转】
转自:https://www.cnblogs.com/virusolf/p/4945642.html http://blog.163.com/he_junwei/blog/static/1979376 ...
- Linux多线程服务器端编程
目录 Linux多线程服务器端编程 线程安全的对象生命期管理 对象的销毁线程比较难 线程同步精要 借shared_ptr实现写时拷贝(copy-on-write) 多线程服务器的适用场合与常用编程模型 ...
随机推荐
- [原创]obj-c编程16:键值编码(KVC)
原文链接:obj-c编程16:键值编码(KVC) 我们可以借助obj-c中的键值编码(以后简称KVC,Key-Value Coding)来存取类的属性,通过指定所要访问的属性名字符串标示符,可以使用存 ...
- Unicode字符列表
注:除非有特别指明,否则以下符号皆属“半角”而非“全角”. 代码 显示 描述 U+0020 空格 U+0021 ! 叹号 U+0022 " 双引号 U+0023 # 井号 U+0024 $ ...
- Silverlight下的Socket通讯
http://www.cnblogs.com/chengxingliang/archive/2012/05/24/2515100.html 在Silverlight中进行通讯,只能使用4502-453 ...
- 第五章 Spring3.0 、Hibernate3.3与Struts2的整合
5.1整合Spring与Hibernate 5.1.1使用MyEclipse加入Spring与Hibernate功能 使用MyEclipse工具主要是为了让工程拥有把数据表生成实体类与映射的功能.然后 ...
- GDKOI2015 Day2
P1 题目描述: 给出一个二分图,选择互不相交的边,使得边覆盖的点权和最大. solution: 简单DP,用树状数组维护最大值. 时间复杂度:$O(n \log n) $ P2 题目描述: 给出N个 ...
- 轻轻谈一下seaJs——模块化开发的利器
"仅做一件事,做好一件事." 这个应该就是seaJs的精髓了. 我在自己的一些项目中使用过seaJs.对其算是了解一二.如今就班门弄斧.轻轻地谈一下. 首先上一段度娘的话: &qu ...
- linux经常使用(一)linux 安装配置 jdk之 找不到安装文件文件夹及source /etc/profile 报unexpected end of file 错误 解决
linux 安装配置 jdk 应该算是一个非常主要的东西.可是我到如今才自己第一次 正式安装.果然出现了问题.. 问题就是 安装之后 找不到 安装路径 ,进而没法配置环境变量. 现象例如以下: 提示 ...
- ubuntu14.04 Markdown编辑器推荐之Remarkable
如今已经习惯了用Markdown编辑器写博文的习惯,那么ubuntu以下有什么好用的呢?搜索中发现了这个叫Remarkable的免费Markdown编辑器.为什么推荐这个呢?说说它的特点: 实时预览 ...
- Android中的数据存储
Android中的数据存储主要分为三种基本方法: 1.利用shared preferences存储一些轻量级的键值对数据. 2.传统文件系统. 3.利用SQLite的数据库管理系统. 对SharedP ...
- winfrom播放动态图片
winfrom是不能直接加载的动态图片的.只能够自己写方法实现. 具体代码如下: using System; using System.Collections.Generic; using Syste ...