pthread基本操作

  • 进程的创建(pthread_create)


int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg)

RETURN VALUE

On success, pthread_create() returns 0; on error, it returns an error number.
函数参数:
  1. pthread_t *thread, 传入创建的pthread_t指针。
  2.const pthread_attr_t *attr,修改进程的属性,如果不设置则可以传入NULL
  3.void *(*start_routine) (void *)创建出来的进程执行的函数,返回类型为void*,并且需要带参数void*
  4. void *arg 传入的函数参数。

在给函数传参数的时候,如果只是单纯的传入数字,我们可以采用(大致的写几行伪代码):

void* fun(void *arg){
int i = (argumentType)arg;
}
main(){
int i;
pthread_t pid;
pthread_create(&pid,NULL,fun,(void*)i);}

如果是在32位操作系统,此代码中的argumentType应该写为int,因为void*指针的大小也是4位。

如果是在64位操作系统,此代码中的argumentType应该写为long,因为void*指针的大小是8位,如果使用int会报错而不通过编译。

这里采用int转void*,而不是int* 转 void*的原因是,如果实在多线程的创建过程中,传递的是地址,其他线程如果修改这个数据,在本线程的后续操作中会使数据改变而导致达不到自己想要的效果。

当我们需要传递多个参数的时候,便可以采用结构体,定义一个结构体数据,然后通过指针传递给函数,接着转换一下类型就好了。

  • pthread_join, pthread_detach
typedef struct retval{
    int id;
    char str[10];
}*pretval;
void *fun1(void *arg){
    pretval argtemp = (pretval)arg;
    argtemp->id = 123123;
    printf("%d,%s\n",argtemp->id,argtemp->str);
    pthread_exit(argtemp);
}
int main()
{
    pthread_t pthread1;
    retval* arg = new retval;
    arg->id = 10;
    strcpy(arg->str,"hello123");
    int rect = pthread_create(&pthread1,NULL,fun1,(void*)arg);
    pthread_join(pthread1,(void **)&arg);
    printf("this is main %d %s\n",arg->id,arg->str);
}

pthread_join用来回收线程,需要指定回收线程的ID和线程的返回参数(可选),这个例子是使用结构提体参,在线程函数中改变结构体变量的值,然后传递给pthread_join,接着显示修改后的值。这样基本上就了解了pthread_join的用法,另外pthread_join是阻塞函数。

如果不回收死亡的线程,便会产生僵尸线程。

pthread_detach使用来分离线程,如果我们使用了pthread_detach,那么这个进程在执行完自己的任务之后便会自动死亡并回收。

但是如果使用了detach之后,再使用join,join的返回值将会是错误的number,好像是22。

如果我们使用很多的线程,使用pthread_detach是有一点不太方便,这个时候我们便可以使用上面pthread_create函数的第二个参数来设置创建进程的属性。

#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void *fun(void *){
    printf("hello\n");
    //pthread_cond_timedwait();
    exit(1);
    return NULL;
}
int main()
{
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
    pthread_t pid;
    pthread_create(&pid,&attr,fun,NULL);
    sleep(20);
    return 0;
}

 

需要注意的是需要初始化之后赋值才能使用,不然有可能会达不到你的期望。

  • pthread_cancel

 pthread_cancel,是计算机语言,它发送终止信号给thread线程,如果成功则返回0,否则为非0值。

  • 有关线程的退出问题

接下来我们聊聊exit,_exit,return,pthread_exit.

_exit():会结束整个进程,不论缓冲区是否有数据。

exit():会结束整个进程,缓冲区有数据就写到指定的文件描述符。

return:只是单纯的返回到函数到用的地方,但是当main函数使用的时候,就会退出整个进程,所以要使用pthread_exit.如果是其他线程,则只会退出自己。

pthread_exit:只会退出单个线程,不影响其他线程。

 

posted @ 2020-07-03 10:29  缄默先生  阅读(745)  评论(0编辑  收藏  举报