#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多线程示例的更多相关文章

  1. 《Linux多线程服务端编程:使用muduo C++网络库》上市半年重印两次,总印数达到了9000册

    <Linux多线程服务端编程:使用muduo C++网络库>这本书自今年一月上市以来,半年之内已经重印两次(加上首印,一共是三次印刷),总印数达到了9000册,这在技术书里已经算是相当不错 ...

  2. Linux 多线程应用中如何编写安全的信号处理函数

    http://blog.163.com/he_junwei/blog/static/1979376462014021105242552/ http://www.ibm.com/developerwor ...

  3. LINUX多线程(一)(创建和退出)

    1. Linux多线程概述 1.1. 概述 进程是系统中程序执行和资源分配的基本单位.每个进程有自己的数据段.代码段和堆栈段.这就造成进程在进行切换等操作时都需要有比较负责的上下文切换等动作.为了进一 ...

  4. 笔记整理--Linux多线程

    Unix高级环境编程系列笔记 (2013/11/17 14:26:38) Unix高级环境编程系列笔记 出处信息 通过这篇文字,您将能够解答如下问题: 如何来标识一个线程? 如何创建一个新线程? 如何 ...

  5. Linux多线程编程初探

    Linux线程介绍 进程与线程 典型的UNIX/Linux进程可以看成只有一个控制线程:一个进程在同一时刻只做一件事情.有了多个控制线程后,在程序设计时可以把进程设计成在同一时刻做不止一件事,每个线程 ...

  6. Linux 多线程 - 线程异步与同步机制

    Linux 多线程 - 线程异步与同步机制 I. 同步机制 线程间的同步机制主要包括三个: 互斥锁:以排他的方式,防止共享资源被并发访问:互斥锁为二元变量, 状态为0-开锁.1-上锁;开锁必须由上锁的 ...

  7. ZT 为什么pthread_cond_t要和pthread_mutex_t同时使用 || pthread/Linux多线程编程

    为什么线程同步的时候pthread_cond_t要和pthread_mutex_t同时使用 (2009-10-27 11:07:23) 转载▼ 标签: 杂谈 分类: 计算机 举一个例子(http:// ...

  8. Linux 多线程应用中如何编写安全的信号处理函数【转】

    转自:https://www.cnblogs.com/virusolf/p/4945642.html http://blog.163.com/he_junwei/blog/static/1979376 ...

  9. Linux多线程服务器端编程

    目录 Linux多线程服务器端编程 线程安全的对象生命期管理 对象的销毁线程比较难 线程同步精要 借shared_ptr实现写时拷贝(copy-on-write) 多线程服务器的适用场合与常用编程模型 ...

随机推荐

  1. sql语句操作记录

    发觉一些sql语句写出来的时候不停忘记,做一个记录. mySQL .查看表的创建过程sql语句和注释,注释是在创建表的过程中增加comment,后面跟随注释的内容 SHOW CRATE TABLE T ...

  2. J2SE知识点摘记(十八)

    Java容器类类库的用途是“保存对象”,并将其划分为两个不同的概念: 1)  Collection . 一组对立的元素,通常这些元素都服从某种规则.List必须保持元素特定的顺序,而Set 不能有重复 ...

  3. sim卡中短信简要格式

    //SELECT A0 A4 00 00 02 3F 00 9F 17 //A0 A4 00 00 02 是命令头,CLA = A0表示GSM应用,INS = A4 表示SELECT,P1 P2 =  ...

  4. ObjectiveC中的block用法解析

    Block Apple 在C, Objective-C,C++加上Block这个延申用法.目前只有Mac 10.6 和iOS 4有支持.Block是由一堆可执行的程序组成,也可以称做没有名字的Func ...

  5. [转] C#.Net Socket网络通讯编程总结

    1.理解socket1).Socket接口是TCP/IP网络的应用程序接口(API).Socket接口定义了许多函数和例程,程序员可以用它们来开发TCP/IP网络应用程序.Socket可以看成是网络通 ...

  6. JavaScript之firstChild属性、lastChild属性、nodeValue属性学习

    1.数组元素childNodes[0]有更直观易读的优点,这边在介绍一个有同样功能的属性,且更加语义化-------->firstChild属性 假设我们需要目标元素节点下的所有子元素中的第一个 ...

  7. <转>ASP.NET学习笔记之MVC 3 数据验证 Model Validation 详解

    MVC 3 数据验证 Model Validation 详解  再附加一些比较好的验证详解:(以下均为引用) 1.asp.net mvc3 的数据验证(一) - zhangkai2237 - 博客园 ...

  8. [转]eclipse借助hibernate tool从数据库逆向生成Hibernate实体类

    如何从数据库逆向生成Hibernate实体类呢??? 1. 首先,要在eclipse中采用自带的数据库管理器(Data Management),连通你的数据库: 然后选择数据库,这里用的oracle, ...

  9. java中关于线程间协作所用关键字synchronized,wait,notify的用法

    wait/notify()关键字适用于一个线程通知另一个线程所需的条件状态已就绪,最常用于线程在循环中休眠直到获取特定条件的场景. 例如,一个线程一直等待直到队列中有一个组件能够处理:当组件添加到队列 ...

  10. C++/C# 最基本的Marshal和Ptr

    Vidyo32.VidyoClientInEventLogin Login = new Vidyo32.VidyoClientInEventLogin(); Login.portalUri = thi ...