linux中线程的基本控制--创建、退出、连接及取消

pthread_create函数: 线程创建
原函数:pthread_create(pthread *restrict tidp,
           const pthread_attr_t *restrict attr,
           void *(*start_routine)(void *),
           void *restrict arg)
参数:新线程ID,如果成功则新线程的ID回填充到tidp的内存
   线程属性(调度策略,继承性,分高性)
   回调函数(新线程要执行的函数)
   回调函数的参数
返回值:成功返回0,失败则返回错误码
例:int err =pthread_create(&ntid,NULL,thread_fun,“new thread”);

编译时需要连接库libpthread
例:gcc -o main main.c -lpthread

注: linux中的pthread_t 并不是一个结构体,而是unsigned long int

#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include <sys/types.h>
void print_id(char *s)
{
	pid_t pid;
	pthread_t tid;
	
	pid = getpid();
	tid = pthread_self();

	printf("%s pid is %u, tid is 0x%x\n",s,pid,(unsigned int)tid); 
}
void *thread_fun(void *arg)
{
	print_id(arg);
	return (void *)0;
}
int main()
{
	pthread_t ntid;
	int err;

	err = pthread_create(&ntid,NULL,thread_fun,"new thread");
	if(err!=0)
	{
		printf("create new thread fail\n");
		return 0;
	}
	print_id("main thread:");
	sleep(2);
	return 0;
}

运行结果

main thread: pid is 4857, tid is 0xfd6b9700
new thread pid is 4857, tid is 0xfcecb700

return、pthread_exit、exit
其中exit会导致进程退出

#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include <sys/types.h>
void *thread_fun(void *arg)
{
	if(strcmp("1",(char *)arg)==0)
	{
		printf("new thread return!\n");
		return (void *)1;
	}
	if(strcmp("2",(char *)arg)==0)
	{
		printf("new thread pthread_exit!\n");
		pthread_exit((void *)2);
	}
	if(strcmp("2",(char *)arg)==0)
	{
		printf("new thread exit!\n");
		exit(3);
	}
}
int main(int argc, char *argv[])
{
	int err;
	pthread_t tid;
	
	err = pthread_create(&tid,NULL,thread_fun,(void *)argv[1]);
	if(err!=0)
	{
		printf("create new thread failed\n");
		return 0;
	}
	sleep(1);
	printf("main thread\n");
	return 0;
}

运行结果

./pthread_exit 1
new thread return!
main thread
./pthread_exit 2
new thread pthread_exit!
main thread
./pthread_exit 3
main thread

pthread_join函数: 调用该函数的线程会一直阻塞,直到指定的线程id调用pthread_exit、从启动例程返回或者取消
原函数:int pthread_join(pthread_t tid,void ** rval)
参数:tid,指定线程的id
   rval,指定线程的返回码,如果线程被取消,那么rval被置为PTHREAD_CANCELED
返回值:成功会返回0,失败返回错误码
例:err = pthread_join(tid1,(void*) &fp);
注: 调用pthread_join会使指定的线程处于分离的状态,如果指定线程已经处于分离状态,那么调用就会失败。

pthread_detach函数: 可以分离一个线程,线程可以自己分离自己
原函数:int pthread_detach(pthread_t thread);
参数:线程的id
返回值:成功返回0,失败返回错误码
例:pthread_detach(pthread_self());

pthread_self函数: 获得线程自身的ID

#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include <sys/types.h>
void *thread_fn1(void *arg)
{
	printf("thread 1\n");
	pthread_exit((void *)1);
}
void *thread_fn2(void *arg)
{
	printf("thread 2\n");
	pthread_detach(pthread_self());
	pthread_exit((void *)2);
}
int main()
{
	int err1,err2;
	pthread_t tid1,tid2;
	void *rval1,*rval2;
	
	err1 = pthread_create(&tid1,NULL,thread_fn1,NULL);
	err2 = pthread_create(&tid2,NULL,thread_fn2,NULL);
	if(err1|| err2)
	{
		printf("creat thread failed\n");
	}
	printf("main thread\n");
	printf("join1 rval is %d\n",pthread_join(tid1,&rval1));
	printf("join2 rval is %d\n",pthread_join(tid2,&rval2));

	printf("thread 1 exit code is %d\n",(int *)rval1);
	printf("thread 2 exit code is %d\n",(int *)rval2);
 }

运行结果

main thread
thread 2
thread 1
join1 rval is 0
join2 rval is 22
thread 1 exit code is 1
thread 2 exit code is 201205200

注: 线程2中调用了pthread_detach,无法连接,故返回错误码

pthread_cancel函数: 取消线程函数
原函数:int pthread_cancel(pthread_t tid)
参数:需要取消的线程的id
返回值:成功返回0,失败返回错误码
例:int cval=pthread_cancel(tid);
注: 取消tid指定的线程,所谓的取消只是发送一个请求,并不意味着等待线程终止,而且发送成功也不代表线程一定会终止。该函数需要被取消线程的配合,线程在很多时候会查看自己是否有取消请求,如果有就主动退出,这个查看是否有取消的地方称为取消点。

pthread_setcancelstate函数: 设置线程对取消信号的反应
原函数:int pthread_setcancelstate(int state,int *oldstate)
参数:state,PTHREAD_CAMCEL_ENABLE(响应取消信号)
       PTHREAD_CANCEL_DISABLE(忽略取消信号)
   oldstate,如果不为NULL则是存储原来的取消状态以便恢复
返回值:成功返回0 ,失败返回错误码
例:int stateval=pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
注: 取消状态,就是线程对取消信号的处理方式,忽略或者响应。线程创建时默认的是响应取消信号。

pthread_setcanceltype函数: 设置线程取消动机的执行时机
原函数:int pthread_setcanceltype(int type, int *oldtype)
参数:type,PTHREAD_CANCEL_DEFERRED(收到取消信号后继续运行至下一个取消点再退出)
      PTHREAD_CANCEL_ASYNCHRONOUS(收到取消信号后立即退出)。
      注:这两个参数是在线程响应取消信号的时候才有作用(PTHREAD_CAMCEL_ENABLE)
   oldtype,oldtype如果不设置为NULL则存储运来的取消动作类型值。
返回值:成功返回0,失败返回错误码
例:int typeval=pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,NULL);
注: 取消类型,是线程对取消信号的响应方式,立即取消或者延时取消。线程创建时默认是延时取消。

取消点: 取消一个线程,它通常需要被取消线程的配合。
很多地方都是包含取消点,包括:pthread_join()、 pthread_testcancel()、pthread_cond_wait()、 pthread_cond_timedwait()、sem_wait()、sigwait()、write、read,大多数会阻塞的系统调用

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
void *thread_fun(void *arg)
{
        int stateval;
        int typeval;
        //设置不响应取消信号
		stateval=pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL);
        if(stateval != 0)
        {
                printf("set cancel state failure\n");
        }
        printf("new thread\n");
        //睡眠,返回执行主线程
        sleep(4);
 
        printf("about to cancel\n");
        //设置为响应取消信号
        stateval=pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
        if(stateval != 0)
        {
                printf("set cancel state failure\n");
        }
        //取消方式为延迟取消
        typeval=pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,NULL);
        if(typeval != 0)
        {
                printf("set cancel type failure\n");
        }
        //因为设置的是延迟取消,所以在第一个取消点到来时就会取消,所以看不到第二句话的打印信息
        printf("first cancel point\n");
        printf("second cancel point\n");
        return (void *)10;
}
int main()
{
        pthread_t tid;
        int err,cval,jval;
        void *rval;
        //创建新的线程
        err=pthread_create(&tid,NULL,thread_fun,NULL);
        if(err != 0)
        {
                printf("create thread failure\n");
                return -1;
        }
        //睡眠,执行新的线程
        sleep(2);
        //发送取消信号
        cval=pthread_cancel(tid);
        if(cval != 0)
        {
                printf("cancel thread failure\n");
        }
        jval=pthread_join(tid,&rval);
 
        printf("new thread exit code is %d\n",(int *)rval);
        return 0;
}

运行结果

new thread
about to cancel
first cancel point
new thread exit code is -1
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值