【linux草鞋应用编程系列】_4_ 应用程序多线程
一、应用程序多线程
SYNOPSIS
#include <pthread.h> int pthread_create(pthread_t *restrict thread, //标志线程的变量地址
const pthread_attr_t *restrict attr, //创建的线程的属性
void *(*start_routine)(void*), //线程回调处理函数
void *restrict arg //传递给线程回调函数的参数
);
SYNOPSIS
#include <pthread.h> void pthread_exit(void *value_ptr //线程回调函数的返回值, 相当于线程回调函数的 return 的返回值。
);
SYNOPSIS
#include <pthread.h> int pthread_join(pthread_t thread, //调用进程需要等待的线程标志变量
void **value_ptr //输出参数,如果整个参数不为空,那么就指向线程回调函数的返回值
);
SYNOPSIS
#include <pthread.h> int pthread_detach(pthread_t thread //要自动释放系统资源的线程的标志
);
SYNOPSIS
#include <pthread.h> pthread_t pthread_self(void);
SYNOPSIS
#include <pthread.h> int pthread_cancel(pthread_t thread //接受请求的线程的标志
);
SYNOPSIS
#include <pthread.h> //pthread_setcancelstate用来设置线程的取消状态,禁止取消或者使能取消, 默认为使能的
int pthread_setcancelstate(int state, //线程要设置的状态
int *oldstate //线程原来的状态
);
//pthread_setcanceltype函数用来设置线程的取消类型,
int pthread_setcanceltype(int type,
int *oldtype
);
//pthread_testcancel函数用来设置线程的撤销点
void pthread_testcancel(void);
#include <stdio.h>
#include <pthread.h> void* thread_test(void* argv)
{
int i;
for(i=;i<;i++)
{
printf("in thread_test the i =%d.\n",i);
}
return NULL;
} int main(void)
{
int i;
pthread_t pthread; //创建一个新的线程
pthread_create(&pthread,NULL,thread_test,NULL); for(i=;i<;i++)
{
printf("in main function the i=%d.\n",i);
}
return ;
}
[root@localhost thread]# ./a.out
in main function the i=0.
in main function the i=1.
in main function the i=2.
in main function the i=3.
#include <stdio.h>
#include <pthread.h> void* thread_test(void* argv)
{
int i;
for(i=;i<;i++)
{
printf("in thread_test the i =%d.\n",i);
} return NULL;
} int main(void)
{
int i;
int* thread_val=NULL;
pthread_t pthread; //创建一个新的线程
pthread_create(&pthread,NULL,thread_test,NULL);
pthread_join(pthread,(void *)&thread_val); //增加线程资源释放方式 for(i=;i<;i++)
{
printf("in main function the i=%d.\n",i);
}
return ;
}
[root@localhost thread]# gcc -lpthread main.c
[root@localhost thread]# ./a.out
in thread_test the i =.
in thread_test the i =.
in thread_test the i =.
in thread_test the i =.
in main function the i=.
in main function the i=.
in main function the i=.
in main function the i=.
//创建一个新的线程
pthread_create(&pthread,NULL,thread_test,NULL);
//这里的语句放到下面了
for(i=;i<;i++)
{
printf("in main function the i=%d.\n",i);
pthread_join(pthread,(void *)&thread_val); //将设定线程资源释放方式函数放到这里
}
[root@localhost thread]# gcc -lpthread main.c
[root@localhost thread]# ./a.out
in main function the i=.
in thread_test the i =.
in thread_test the i =.
in thread_test the i =.
in thread_test the i =.
in main function the i=.
in main function the i=.
in main function the i=.
#include <stdio.h>
#include <pthread.h> void* thread_test(void* argv)
{
int i; for(i=;i<;i++)
{
printf("in thread_test the i =%d.\n",i);
sleep();
} pthread_exit((void*));
} int main(void)
{
unsigned int i;
int* thread_val=NULL;
pthread_t pthread; if( pthread_create(&pthread,NULL,thread_test,(void*)&thread_val) )
{
perror("pthread create");
}
if(pthread_detach(pthread))
{
perror("pthread detach");
} for(i=;i<;i++)
{
printf("in main function the i=%d.\n",i);
}
return ;
}
[root@localhost thread]# gcc main.c -lpthread
[root@localhost thread]# ./a.out | grep test
in thread_test the i =.
in thread_test the i =.
in thread_test the i =.
in thread_test the i =.
[root@localhost thread]# cat main.c
#include <stdio.h>
#include <pthread.h> void* thread_test(void* argv)
{
int i; for(i=;i<;i++)
{
printf("in thread_test the i =%d.\n",i);
sleep();
} pthread_exit((void*));
} int main(void)
{
unsigned int i;
int* thread_val=NULL;
pthread_t pthread; //创建一个新的线程
if( pthread_create(&pthread,NULL,thread_test,(void*)&thread_val) )
{
perror("pthread create");
}
if(pthread_detach(pthread))
{
perror("pthread detach");
} for(i=;i<;i++)
{
printf("in main function the i=%d.\n",i);
sleep();
} return ;
}
[root@localhost thread]# ./a.out
in main function the i=.
in thread_test the i =. //可以发现线程交替执行
in main function the i=.
in thread_test the i =.
in main function the i=.
in thread_test the i =.
in main function the i=.
in thread_test the i =.
in main function the i=.
root@localhost thread]# cat main.c
#include <stdio.h>
#include <pthread.h> void* thread_test(void* argv)
{
int i;
pthread_detach(pthread_self()); //通过pthread_self()获取本线程的线程标志
for(i=;i<;i++)
{
printf("in thread_test the i =%d.\n",i);
sleep();
}
pthread_exit((void*));
} int main(void)
{
unsigned int i;
int* thread_val=NULL;
pthread_t pthread;
//创建一个新的线程
if(pthread_create(&pthread,NULL,thread_test,NULL))
{
perror("pthread create");
}
for(i=;i<;i++)
{
printf("in main function the i=%d.\n",i);
sleep();
}
return ;
}
[root@localhost thread]# ./a.out
in main function the i=.
in thread_test the i =.
in main function the i=.
in thread_test the i =.
in main function the i=.
in thread_test the i =.
in main function the i=.
in thread_test the i =.
in main function the i=.
SYNOPSIS
#include <pthread.h> int pthread_mutex_init(pthread_mutex_t *restrict mutex, //待初始化互斥量的指针
const pthread_mutexattr_t *restrict attr //待初始化互斥量要设置的属性
);
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; //静态初始化互斥量
int pthread_mutex_destroy(pthread_mutex_t *mutex //要销毁初始化状态互斥量的指针
);
SYNOPSIS
#include <pthread.h> int pthread_mutex_lock(pthread_mutex_t *mutex //要获取的互斥锁的指针
);
int pthread_mutex_trylock(pthread_mutex_t *mutex //要获取的互斥锁的指针
);
int pthread_mutex_unlock(pthread_mutex_t *mutex //要释放的互斥锁的指针
);
#include <stdio.h>
#include <pthread.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h> typedef struct {
int fd;
pthread_mutex_t p_mutex;
}p_fd_t; void* thread_test(void* argv)
{
int i;
int j;
int size;
char buf[];
p_fd_t* fd_mutex; pthread_detach(pthread_self()); //将传递进来的参数变为结构题指针
fd_mutex=(p_fd_t *)argv; //加锁
pthread_mutex_lock(&fd_mutex->p_mutex);
for(i=;i<;i++)
{
j=;
size=sprintf(buf,"the pthred id is: %d\n",pthread_self());
while(j<size)
{
write(fd_mutex->fd,&buf[j++],);
usleep();
}
}
//解锁
pthread_mutex_unlock(&fd_mutex->p_mutex); pthread_exit((void*));
} int main(void)
{
unsigned int i;
int j;
int size;
int fd;
char buf[];
pthread_t pthread;
p_fd_t fd_mutex=
{
.p_mutex=PTHREAD_MUTEX_INITIALIZER, //初始化线程互斥锁
}; //打开或者创建一个文件
fd=open("./test",O_RDWR | O_CREAT | O_TRUNC, );
if(- == fd)
{
perror("open ./test");
exit();
} fd_mutex.fd=fd;
//创建一个新的线程
if(pthread_create(&pthread,NULL,thread_test,(void*)&fd_mutex))
{
perror("pthread create");
} //加锁
pthread_mutex_lock(&fd_mutex.p_mutex);
for(i=;i<;i++)
{
j=;
size=sprintf(buf,"the main pthred id is: %d\n",pthread_self());
while(j<size)
{
write(fd_mutex.fd,&buf[j++],);
usleep();
}
}
//解锁
pthread_mutex_unlock(&fd_mutex.p_mutex); sleep(); //加上时间等待 线程结束
//在主线程结束之间销毁线程互斥锁资源
pthread_mutex_destroy(&fd_mutex.p_mutex);
close(fd); return ;
}
[root@localhost thread]# cat test
the main pthred id is: -
the main pthred id is: -
the main pthred id is: -
the main pthred id is: -
the main pthred id is: - //前面的是主线程写入文件的内容,后面是线程写入到内容
the pthred id is: -
the pthred id is: -
the pthred id is: -
the pthred id is: -
the pthred id is: -
[root@localhost thread]#
#include <stdio.h>
#include <pthread.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h> typedef struct {
int fd;
pthread_mutex_t p_mutex;
}p_fd_t; void* thread_test(void* argv)
{
int i;
int j;
int size;
char buf[];
p_fd_t* fd_mutex; pthread_detach(pthread_self()); //将传递进来的参数变为结构题指针
fd_mutex=(p_fd_t *)argv; //加锁
/*pthread_mutex_lock(&fd_mutex->p_mutex);*/
for(i=;i<;i++)
{
j=;
size=sprintf(buf,"the pthred id is: %d\n",pthread_self());
while(j<size)
{
write(fd_mutex->fd,&buf[j++],);
usleep();
}
}
//解锁
/*pthread_mutex_unlock(&fd_mutex->p_mutex);*/ pthread_exit((void*));
} int main(void)
{
unsigned int i;
int j;
int size;
int fd;
char buf[];
pthread_t pthread;
p_fd_t fd_mutex=
{
.p_mutex=PTHREAD_MUTEX_INITIALIZER, //初始化线程互斥锁
}; //打开或者创建一个文件
fd=open("./test",O_RDWR | O_CREAT | O_TRUNC, );
if(- == fd)
{
perror("open ./test");
exit();
} fd_mutex.fd=fd;
//创建一个新的线程
if(pthread_create(&pthread,NULL,thread_test,(void*)&fd_mutex))
{
perror("pthread create");
} //加锁
/*pthread_mutex_lock(&fd_mutex.p_mutex);*/
for(i=;i<;i++)
{
j=;
size=sprintf(buf,"the main pthred id is: %d\n",pthread_self());
while(j<size)
{
write(fd_mutex.fd,&buf[j++],);
usleep();
}
}
//解锁
/*pthread_mutex_unlock(&fd_mutex.p_mutex);*/ sleep(); //加上时间等待 线程结束
//在主线程结束之间销毁线程互斥锁资源
pthread_mutex_destroy(&fd_mutex.p_mutex);
close(fd); return ;
}
[root@localhost thread]# vim pthread.mutex.c
[root@localhost thread]# gcc pthread.mutex.c -lpthread
[root@localhost thread]# ./a.out
[root@localhost thread]# cat test
tthhee m apitnh prtehdr eidd iids :i s-: -
44t
thhee mapitnh rpetdh riedd i di sis:: --
0t8h
e tmhaein pptthhrreedd iidd iiss:: -- tthhee mpatihnr epdt hirded iisd: i-s1: -
4t4
hteh ep tmhariend pitdh riesd: i-d1 2i0s8: - [root@localhost thread]#
【linux草鞋应用编程系列】_4_ 应用程序多线程的更多相关文章
- 【linux草鞋应用编程系列】_5_ Linux网络编程
一.网络通信简介 第一部分内容,暂时没法描述,内容实在太多,待后续专门的系列文章. 二.linux网络通信 在linux中继承了Unix下“一切皆文件”的思想, 在linux中要实现网 ...
- 【linux草鞋应用编程系列】_6_ 重定向和VT100编程
一.文件重定向 我们知道在linux shell 编程的时候,可以使用文件重定向功能,如下所示: [root@localhost pipe]# echo "hello world&q ...
- 【linux草鞋应用编程系列】_3_ 进程间通信
一.进程间通信 linux下面提供了多种进程间通信的方法, 管道.信号.信号量.消息队列.共享内存.套接字等.下面我们分别 介绍管道.信号量.消息队列.共享内存. 信号和套 ...
- 【linux草鞋应用编程系列】_2_ 环境变量和进程控制
一. 环境变量 应用程序在执行的时候,可能需要获取系统的环境变量,从而执行一些相应的操作. 在linux中有两种方法获取环境变量,分述如下. 1.通过main函数的参数获取环境变量 ...
- 【linux草鞋应用编程系列】_1_ 开篇_系统调用IO接口与标准IO接口
最近学习linux系统下的应用编程,参考书籍是那本称为神书的<Unix环境高级编程>,个人感觉神书不是写给草鞋看的,而是 写给大神看的,如果没有一定的基础那么看这本书可能会感到有些头重脚轻 ...
- linux高性能服务器编程 (八) --高性能服务器程序框架
第八章 高性能服务器编程框架 这一章主要介绍服务器的三个主要模块: I/O处理单元.逻辑单元.存储单元.另外服务器的模型有:C/S模型和P2P模型.虽然服务器模型比较多,但是其核心框架都一样,只是在于 ...
- Linux高性能服务器编程:高性能服务器程序框架
服务器有三个主要模块: (1)I/O处理单元 (2)逻辑单元 (3)存储单元 1.服务器模型 C/S模型 逻辑:服务器启动后,首先创建一个或多个监听socket,并调用bind函数将其绑定到服务器感兴 ...
- MapReduce 编程 系列七 MapReduce程序日志查看
首先,假设须要打印日志,不须要用log4j这些东西,直接用System.out.println就可以,这些输出到stdout的日志信息能够在jobtracker网站终于找到. 其次,假设在main函数 ...
- 介绍linux设备驱动编程
目前,Linux软件工程师大致可分为两个层次: (1)Linux应用软件工程师(Application Software Engineer): 主要利用C库函数和Linux API进行应用 ...
随机推荐
- C#设计模式之组合
IronMan之组合 在上个篇幅中讲到怎么把“武器”装饰到“部件”上,这个篇幅呢,还是要讲到“武器”,不过呢是关于“武器”使用的. 本篇介绍"武器"的合理使用方式,不说废话,直接来 ...
- 老司机学新平台 - Xamarin Forms开发框架之MvvmCross插件精选
在前两篇老司机学Xamarin系列中,简单介绍了Xamarin开发环境的搭建以及Prism和MvvmCross这两个开发框架.不同的框架,往往不仅仅使用不同的架构风格,同时社区活跃度不同,各种功能模块 ...
- 《Entity Framework 6 Recipes》中文翻译系列 (10) -----第二章 实体数据建模基础之两实体间Is-a和Has-a关系建模、嵌入值映射
翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 2-11 两实体间Is-a和Has-a关系建模 问题 你有两张有Is-a和Has-a ...
- 《Entity Framework 6 Recipes》中文翻译系列 (24) ------ 第五章 加载实体和导航属性之查询内存对象
翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 5-4 查询内存对象 问题 你想使用模型中的实体对象,如果他们已经加载到上下文中, ...
- C# 用原生JS进行文件的上传
1.此文章是用原生JS来进行文件的上传,有两个版本,一个不用ajax,一个用ajax. 1)非AJAX <!DOCTYPE html> <html> <head> ...
- Java基础-服务器的发送和接收
package hanqi.test; import java.io.IOException; import java.io.OutputStream; import java.io.PrintWri ...
- 【深入浅出Linux网络编程】 “基础 -- 事件触发机制”
回顾一下“"开篇 -- 知其然,知其所以然"”中的两段代码,第一段虽然只使用1个线程但却也只能处理一个socket,第二段虽然能处理成百上千个socket但却需要创建同等数量的线程 ...
- jquery 拖拽,框选的一点积累
拖拽draggable,框选 selectable,按ctrl多选,临近辅助对齐,从工具栏拖工具 等,和jqueryui的selectable不同,是在一个父div里框选子div(类似框选文件),一 ...
- android的logcat详细用法
Android日志系统提供了记录和查看系统调试信息的功能.日志都是从各种软件和一些系统的缓冲区中记录下来的,缓冲区可以通过 logcat 命 令来查看和使用. 使用logcat命令 你可以用 logc ...
- Visual Studio 2015无法进行Package Restore的原因和解决方案
这篇文章是记录在我的当前电脑上面,安装Visual Studio 2015 Community Edition出现的无法进行Package Restore的问题,很可能在你的电脑上面无法重现.我的环境 ...