linux控制线程运行时间,linux下线程控制

线程是计算机中独立运行的最小单位,运行时占用很少的系统资源。在多进程情况下,每个进程都有自己独立的地址空间,而在多线程情况下,同意进程内的线程共享进程的地址空间。因此创建新进程就要耗费时间为其分配系统资源,而创建新线程花费的时间要少得多。

1.创建线程int pthread_create(

pthread_t *thread,  //线程ID

const pthread_attr_t *attr, //线程属性,为NULL/0,使用默认属性

void *(*start_routine) (void *),  //线程代码函数

void *arg);      //传递线程代码的数据例1.创建线程

#include 

#include 

#include     //这是一个外部库,在编译时需要指定链接库-lpthread

void * thread(void *data)

{

printf("this is thread111,threadid = %ld\n",pthread_self());

}

int main()

{

pthread_t thid;

pthread_create(&thid,NULL,thread,NULL);

//sleep(2);

pthread_join(thid,(void**)0);

return 0;

}

结论:

1.程序结束所有子线程就结束

解决办法: 等待子线程结束

a.sleep/pause

b.pthread_exit(void*retval);

c.int pthread_join(

pthread_t tid,  //等待子线程tid结束

void **retval); //子线程结束的返回值

如果不加等待子线程结束的语句,main函数执行完会直接退出,不会执行子线程

2.创建子线程后,主线程继续完成系统分配的时间片

3.子线程结束就是线程函数返回

4.子线程与主线程有同等优先级别

2.线程基本控制

线程结束可分为内部结束和外部结束:

内部自动结束:(建议,可以看例二)

return 返回值;    只能在线程函数中使用

int pthread_exit(void*);         在任何线程代码中都可以使用,退出当前线程

外部结束一个线程(处理可以参看下边介绍,防止产生问题):

pthread_cancel(pthread_t thread);    会产生一些不可预知的问题

例二:内部结束线程#include 

#include 

#include 

#include 

void * thread(void *data)

{

while(1){

printf("this is thread data:%s\n",data);

//return "thread exit";

pthread_exit("exit");

}

}

int main()

{

pthread_t thid;

char *retavl;

char *data="main";

pthread_create(&thid,NULL,thread,data);

pthread_join(thid,(void**)&retavl);

printf("%s\n",retavl);

return 0;

}#gcc pthread_exit.c -o pthread_exit -lpthread

#./pthread_exit

this is thread data:main

exit

3.多线程问题及介绍

对于一个全局变量资源等信息,线程是共享进程的这些资源,存在多个线程对这些数据资源进行操作时,可能会产生一些问题,导致数据成为脏数据。

为了解决数据脏,可以使用加锁机制;

3.1.互斥锁/互斥量 mutex(强烈要求成对使用,加锁就需要解锁)

(1).定义互斥量 pthread_mutex_t m;

(2).初始化互斥量 1 pthread_mutex_init(pthread_mutex_t *restrict mutex,

const pthread_mutexattr_t *restrict attr);

attr为锁的属性,置NULL/0为默认属性

(3).互斥量操作

置0 pthread_mutex_lock

会判定互斥量若为0:阻塞;为1:先置0,再返回

置1 pthread_mutex_unlock 直接置1返回

(4).释放互斥量pthread_mutex_destroy

例三:使用互斥锁#include 

#include 

//1,定义互斥量

pthread_mutex_t m;

int a=0,b=0;  //线程共享进程的资源(a,b为全局变量),输出时两个线程同时操作,会导致if(a!=b)出错

void display()

{

//3.加锁

pthread_mutex_lock(&m);

a++;

b++;

pthread_mutex_unlock(&m); //解锁

if(a!=b)

{

printf("%d!=%d\n",a,b);

a=b=0;

}

}

void *run1()

{

while(1)

{

display();

}

}

void *run2()

{

while(1)

{

display();

}

}

main()

{

pthread_t thid1, thid2;

//2.初始化锁

pthread_mutex_init(&m,0);

pthread_create(&thid1,NULL,(void*)run1,NULL);

pthread_create(&thid2,NULL,(void*)run2,NULL);

pthread_join(thid1,(void**)0);

pthread_join(thid2,(void**)0);

//4.释放互斥量

pthread_mutex_destroy(&m);

}

如果不使用互斥锁的话会输出两个明明相等的数不相等:

3c604e4290ad36a3e7d9166ac82a087c.png

为了防止这种数据脏的问题,就需要使用互斥锁机制。

3.2死锁问题

在lock与unlock之间,调用pthread_exit或者在线程外部调用pthread_cancel会使其他线程被永久死锁。

pthread_exit退出线程,为了防止造成死锁,可以在pthread_exit语句前使用解锁语句unlock;

pthread_cancel退出线程,防止死锁可以使一对宏,这对宏类似于进程atexit函数:

void pthread_cleanup_push(

void (*routine)(void *),  //回调函数,routine指向处理函数

void *arg);//arg为传递给处理函数的参数

void pthread_cleanup_pop(int execute);

//execute参数表示执行到pthread_cleanup_pop()时是否在弹出清理函数的同时执行该函数,为0表示不执行,非0为执行;这个参数并不影响异常终止时清理函数的执行。

push进去的函数可能在以下三个时机执行:

1,显示的调用pthread_exit();

2,在cancel点线程被cancel。

3,pthread_cleanup_pop()的参数不为0时。

例四:创建两个线程分别输出奇数和偶数#include 

#include 

#include 

pthread_mutex_t m;

void *handle(void *d)

{

printf("退出后调用\n");

}

void *runodd(void *d)

{

int i=0;

for(i=1;;i+=2)

{

pthread_cleanup_push((void*)handle,0);

pthread_mutex_lock(&m);

printf("%d\n",i);

pthread_mutex_unlock(&m);

pthread_cleanup_pop(0);  //如果设置为1,它会每次都调用清理函数,设置为0,只在死锁使执行清理函数

}

}

void *runeven(void *d)

{

int i=0;

for(i=0;;i+=2)

{

pthread_mutex_lock(&m);

printf("%d\n",i);

pthread_mutex_unlock(&m);

}

}

main()

{

pthread_t todd,teven;

pthread_mutex_init(&m,0);

pthread_create(&todd,0,runodd,0);

pthread_create(&teven,0,runeven,0);

sleep(5);

pthread_cancel(todd);

pthread_join(todd,(void**)0);

pthread_join(teven,(void**)0);

pthread_mutex_destroy(&m);

}

在线程代码加锁时,pthread_cancel会使线程在未解锁的情况下退出,从而导致另一个线程获得的所状态为0,一直处于阻塞状态,造成死锁;使用pthread_cleanup_push和pthread_cleanup_pop宏,就可以设置在出现死锁状态时要执行的清理函数,从而解决死锁。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值