Linux系统编程–线程
1.线程概述(与进程的区别及线程的优势)
Linux多线程编程初探 - 峰子_仰望阳光 - 博客园 (cnblogs.com)
线程也有竞争的关系。
2.线程创建等待退出
demo1.c
#include <pthread.h>
#include <stdio.h>
//int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
void *funs(void *arg)
{
printf("t1:%ld\npthread is creat\n",(unsigned long)pthread_self());
printf("parm is %d\n",*((int *)arg));
}
//int pthread_exit(void *rval_ptr);
//int pthread_join(pthread_t thread, void **rval_ptr);
// 返回:若成功返回0,否则返回错误编号
int main()
{
int ret;
pthread_t t1;
int *pret = NULL;
int parm = 100;
ret = pthread_create(&t1,NULL,funs,(void *)&parm); //创建线程
if(ret == 0){
printf("creat t1 is success\n");
}
return 0;
}
运行结果:
编译时需要链上 -lpthread
运行结果与所想不一样(printf(“parm is %d\n”,*((int *)arg));)还没打印就已经结束了,是因为主程序中没有等待返回就已经结束了
demo2.c (返回 int类型)
#include <pthread.h>
#include <stdio.h>
//int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
void *funs(void *arg)
{
static int ret =10; //如果不用static 函数调用结束后就没掉了,会随机返回
printf("t1:%ld\npthread is creat\n",(unsigned long)pthread_self());
printf("parm is %d\n",*((int *)arg));
pthread_exit((void *)&ret); //退出线程
}
//int pthread_exit(void *rval_ptr);
//int pthread_join(pthread_t thread, void **rval_ptr);
// 返回:若成功返回0,否则返回错误编号
int main()
{
int ret;
pthread_t t1;
int *pret = NULL;
int parm = 100;
ret = pthread_create(&t1,NULL,funs,(void *)&parm);
if(ret == 0){
printf("creat t1 is success\n");
}
printf("main:%ld\n",(unsigned long)pthread_self());
pthread_join(t1,(void **)&pret); //等待线程退出·
//pthread_join(t1,NULL);//如果对线程的返回值不感兴趣,可以把rval_ptr置为NULL。在这种情况下,调用pthread_join函数将等待指定的线程终止,但并 //不获得线程的终止状态。
printf("main:t1 qiut:%d\n",*pret);
return 0;
}
运行结果:
demo3.c (返回 char 类型)
#include <pthread.h>
#include <stdio.h>
//int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
void *funs(void *arg)
{
static char *ret = "funs ret quit!";
printf("t1:%ld\npthread is creat\n",(unsigned long)pthread_self());
printf("parm is %d\n",*((int *)arg));
pthread_exit((void *)ret);
}
//int pthread_exit(void *rval_ptr);
//int pthread_join(pthread_t thread, void **rval_ptr);
// 返回:若成功返回0,否则返回错误编号
int main()
{
int ret;
pthread_t t1;
char *pret = NULL;
int parm = 100;
ret = pthread_create(&t1,NULL,funs,(void *)&parm);
if(ret == 0){
printf("creat t1 is success\n");
}
printf("main:%ld\n",(unsigned long)pthread_self());
pthread_join(t1,(void **)&pret);
printf("main: t1 quit:%s\n",pret);
return 0;
}
运行结果:
3.线程共享内存空间的运行结果代码验证
demo4.c
#include <pthread.h>
#include <stdio.h>
int data = 0;
//int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
void *funs(void *arg)
{
printf("t1:%ld\npthread is creat\n",(unsigned long)pthread_self());
printf("parm is %d\n",*((int *)arg));
while(1){
printf("t1_data:%d\n",data++);
sleep(1);
/*
if(data == 4){ //t1不一定能获得4, 线程间相互竞争,有几率得到4
pthread_exit(NULL); //if data == 4 ;退出t1线程
}
*/
}
}
void *funs2(void *arg)
{
printf("t2:%ld\npthread is creat\n",(unsigned long)pthread_self());
printf("parm is %d\n",*((int *)arg));
while(1){
printf("t2_data:%d\n",data++);
sleep(1);
}
}
//int pthread_exit(void *rval_ptr);
//int pthread_join(pthread_t thread, void **rval_ptr);
// 返回:若成功返回0,否则返回错误编号
int main()
{
int ret;
pthread_t t1;
pthread_t t2;
int *pret = NULL;
int parm = 100;
ret = pthread_create(&t1,NULL,funs,(void *)&parm);
if(ret == 0){
printf("creat t1 is success\n");
}
ret = pthread_create(&t2,NULL,funs2,(void *)&parm);
if(ret == 0){
printf("creat t2 is success\n");
}
while(1){
printf("main_data:%d\n",data++);
sleep(1);
}
pthread_join(t1,NULL);
pthread_join(t2,NULL);
return 0;
}
运行结果:
4.线程同步之互斥量加锁解锁
demo5.c
#include <pthread.h>
#include <stdio.h>
int data = 0;
//int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
pthread_mutex_t mutex;//创建锁
//int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
void *funs(void *arg)
{
//int pthread_mutex_lock(*pthread_mutex_t mutex);
pthread_mutex_lock(&mutex);//上锁
printf("t1:%ld\npthread is creat\n",(unsigned long)pthread_self());
printf("parm is %d\n",*((int *)arg));
//int pthread_mutex_unlock(*pthread_mutext_mutex);
pthread_mutex_unlock(&mutex);//解锁
}
void *funs2(void *arg)
{
pthread_mutex_lock(&mutex);//上锁
printf("t2:%ld\npthread is creat\n",(unsigned long)pthread_self());
printf("parm is %d\n",*((int *)arg));
pthread_mutex_unlock(&mutex);//解锁
}
//int pthread_exit(void *rval_ptr);
//int pthread_join(pthread_t thread, void **rval_ptr);
// 返回:若成功返回0,否则返回错误编号
int main()
{
int ret;
pthread_t t1;
pthread_t t2;
int *pret = NULL;
int parm = 100;
pthread_mutex_init(&mutex, NULL); //锁动态初始化
ret = pthread_create(&t1,NULL,funs,(void *)&parm);
if(ret == 0){
printf("creat t1 is success\n");
}
ret = pthread_create(&t2,NULL,funs2,(void *)&parm);
if(ret == 0){
printf("creat t2 is success\n");
}
pthread_join(t1,NULL);
pthread_join(t2,NULL);
//int pthread_mutex_destroy(*pthread_mutex_t mutex);
pthread_mutex_destroy(&mutex);//销毁锁
return 0;
}
运行结果:
5.互斥锁限制共享资源的访问
demo6.c
#include <pthread.h>
#include <stdio.h>
int data = 0;
//int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
pthread_mutex_t mutex;
//int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
void *funs(void *arg)
{
//int pthread_mutex_lock(*pthread_mutex_t mutex);
pthread_mutex_lock(&mutex);
printf("t1:%ld\npthread is creat\n",(unsigned long)pthread_self());
printf("parm is %d\n",*((int *)arg));
//int pthread_mutex_unlock(*pthread_mutext_mutex);
while(1){
printf("t1:%d\n",data++);
sleep(1);
if(data == 4){
pthread_mutex_unlock(&mutex);
printf("t1 quit====================\n");
pthread_exit(NULL);
}
}
}
/*让t1运行到4结束退出线程,刚开始不确定会是哪个线程先运行,到t2,上锁++后解锁,到t1上锁,等data=4时,解锁退出*/
void *funs2(void *arg)
{
printf("t2:%ld\npthread is creat\n",(unsigned long)pthread_self());
printf("parm is %d\n",*((int *)arg));
while(1){
printf("t2:%d\n",data);
pthread_mutex_lock(&mutex);
data++;
pthread_mutex_unlock(&mutex);
sleep(1);
}
}
//int pthread_exit(void *rval_ptr);
//int pthread_join(pthread_t thread, void **rval_ptr);
// 返回:若成功返回0,否则返回错误编号
int main()
{
int ret;
pthread_t t1;
pthread_t t2;
int *pret = NULL;
int parm = 100;
pthread_mutex_init(&mutex, NULL); //锁动态初始化
ret = pthread_create(&t1,NULL,funs,(void *)&parm);
if(ret == 0){
printf("creat t1 is success\n");
}
ret = pthread_create(&t2,NULL,funs2,(void *)&parm);
if(ret == 0){
printf("creat t2 is success\n");
}
pthread_join(t1,NULL);
pthread_join(t2,NULL);
//int pthread_mutex_destroy(*pthread_mutex_t mutex);
pthread_mutex_destroy(&mutex);
return 0;
}
运行结果:
6.什么情况造成死锁
demo7.c
#include <pthread.h>
#include <stdio.h>
int data = 0;
//int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
pthread_mutex_t mutex;
pthread_mutex_t mutex2;
//int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
void *funs(void *arg)
{
//int pthread_mutex_lock(*pthread_mutex_t mutex);
pthread_mutex_lock(&mutex);
sleep(1);
pthread_mutex_lock(&mutex2);
printf("t1:%ld\npthread is creat\n",(unsigned long)pthread_self());
printf("parm is %d\n",*((int *)arg));
//int pthread_mutex_unlock(*pthread_mutext_mutex);
pthread_mutex_unlock(&mutex);
}
void *funs2(void *arg)
{
pthread_mutex_lock(&mutex);
sleep(1);
pthread_mutex_lock(&mutex2);
printf("t2:%ld\npthread is creat\n",(unsigned long)pthread_self());
printf("parm is %d\n",*((int *)arg));
pthread_mutex_unlock(&mutex);
}
//int pthread_exit(void *rval_ptr);
//int pthread_join(pthread_t thread, void **rval_ptr);
// 返回:若成功返回0,否则返回错误编号
int main()
{
int ret;
pthread_t t1;
pthread_t t2;
int *pret = NULL;
int parm = 100;
pthread_mutex_init(&mutex, NULL); //锁动态初始化
pthread_mutex_init(&mutex2, NULL); //锁动态初始化
ret = pthread_create(&t1,NULL,funs,(void *)&parm);
if(ret == 0){
printf("creat t1 is success\n");
}
ret = pthread_create(&t2,NULL,funs2,(void *)&parm);
if(ret == 0){
printf("creat t2 is success\n");
}
pthread_join(t1,NULL);
pthread_join(t2,NULL);
//int pthread_mutex_destroy(*pthread_mutex_t mutex);
pthread_mutex_destroy(&mutex);
return 0;
}
要有两把锁,才能有死锁,当funs锁mutex时,funs2锁mutex2了,funs再想锁mutex2时就拿不到,会一直卡住,同理funs2也是。
使用多把锁时,一定要注意避免死锁
7.线程条件控制实现线程的同步
demo8.c
#include <pthread.h>
#include <stdio.h>
int data = 0;
//int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
pthread_mutex_t mutex;
pthread_cond_t cond;
//int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
void *funs(void *arg)
{
printf("t1:%ld\npthread is creat\n",(unsigned long)pthread_self());
printf("parm is %d\n",*((int *)arg));
while(1){
//int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
pthread_cond_wait(&cond,&mutex); //等待触发条件
printf("t1:%d\n",data);
printf("t1 qiut================\n");
data = 0;
sleep(1);
}
}
void *funs2(void *arg)
{
printf("t2:%ld\npthread is creat\n",(unsigned long)pthread_self());
printf("parm is %d\n",*((int *)arg));
while(1){
printf("t2:%d\n",data);
pthread_mutex_lock(&mutex);
data++;
pthread_mutex_unlock(&mutex);
if(data == 4){
//int pthread_cond_signal(*pthread_cond_t cond);
pthread_cond_signal(&cond); //触发条件
}
sleep(1);
}
}
//int pthread_exit(void *rval_ptr);
//int pthread_join(pthread_t thread, void **rval_ptr);
// 返回:若成功返回0,否则返回错误编号
int main()
{
int ret;
pthread_t t1;
pthread_t t2;
int *pret = NULL;
int parm = 100;
pthread_mutex_init(&mutex, NULL); //锁动态初始化
//int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
pthread_cond_init(&cond,NULL); //条件动态初始化
ret = pthread_create(&t1,NULL,funs,(void *)&parm);
if(ret == 0){
// printf("creat t1 is success\n");
}
ret = pthread_create(&t2,NULL,funs2,(void *)&parm);
if(ret == 0){
// printf("creat t2 is success\n");
}
pthread_join(t1,NULL);
pthread_join(t2,NULL);
//int pthread_mutex_destroy(*pthread_mutex_t mutex);
pthread_mutex_destroy(&mutex);
//int pthread_cond_destroy(*pthread_cond_t cond);
pthread_cond_destroy(&cond); //销毁条件
return 0;
}
运行结果:
此程序中会一直运行,因为data=0;一直都会在赋值。
#include <pthread.h>
#include <stdio.h>
int data = 0;
//int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
pthread_mutex_t mutex;
pthread_cond_t cond;
//int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
void *funs(void *arg)
{
static int cnt = 3;
printf("t1:%ld\npthread is creat\n",(unsigned long)pthread_self());
printf("parm is %d\n",*((int *)arg));
while(1){
//int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
pthread_cond_wait(&cond,&mutex); //等待触发条件
printf("t1:%d\n",data);
printf("t1 qiut================\n");
data = 0;
sleep(1);
cnt--;
if(cnt == 0){ //当cnt=0时;整个程序退出
exit(-1);
}
}
}
void *funs2(void *arg)
{
printf("t2:%ld\npthread is creat\n",(unsigned long)pthread_self());
printf("parm is %d\n",*((int *)arg));
while(1){
printf("t2:%d\n",data);
pthread_mutex_lock(&mutex);
data++;
pthread_mutex_unlock(&mutex);
if(data == 4){
//int pthread_cond_signal(*pthread_cond_t cond);
pthread_cond_signal(&cond); //触发条件
}
sleep(1);
}
}
//int pthread_exit(void *rval_ptr);
//int pthread_join(pthread_t thread, void **rval_ptr);
// 返回:若成功返回0,否则返回错误编号
int main()
{
int ret;
pthread_t t1;
pthread_t t2;
int *pret = NULL;
int parm = 100;
pthread_mutex_init(&mutex, NULL); //锁动态初始化
//int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
pthread_cond_init(&cond,NULL); //条件动态初始化
ret = pthread_create(&t1,NULL,funs,(void *)&parm);
if(ret == 0){
// printf("creat t1 is success\n");
}
ret = pthread_create(&t2,NULL,funs2,(void *)&parm);
if(ret == 0){
// printf("creat t2 is success\n");
}
pthread_join(t1,NULL);
pthread_join(t2,NULL);
//int pthread_mutex_destroy(*pthread_mutex_t mutex);
pthread_mutex_destroy(&mutex);
//int pthread_cond_destroy(*pthread_cond_t cond);
pthread_cond_destroy(&cond); //销毁条件
return 0;
}
用程序测试:
int main(int argc,char **argv)
//int main()
{
int i=0;
int time;
time = atoi(argv[1]);
// time = 5;
for(i = 0; i < time ;i++){
system("./demo8");
}
}
./a.out 10 >>test.txt &
运行10次,将结果放在test.txt中,& 后台运行
运行结果:
cond 和 mutex初始化
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;//静态初始化
pthread_mutex_init(&mutex, NULL); //动态初始化
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;//静态初始化
pthread_cond_init(&cond, NULL); //动态初始化