pthread多线程基础知识学习

pthread多线程基础知识学习

定义
POSIX线程(POSIX threads),简称Pthreads,是线程的POSIX标准。该标准定义了创建和操纵线程的一整套API。在类Unix操作系统(Unix、Linux、Mac OS X等)中,都使用Pthreads作为操作系统的线程。Windows操作系统也有其移植版[pthreads-win32][6]。
数据类型
  • pthread_t:线程ID
  • pthread_attr_t:线程属性
常用函数
  • pthread_create
    int pthread_create(pthread_t tidp,const pthread_attr_t *attr,(void)(start_rtn)(void),void *arg);
    第一个参数是进程的名字,指针变量,第二个属性设置,NULL,没有属性,第三个是线程运行的起始地址,注意格式,最后一个是运行函数的参数。
  • pthread_join()
    阻塞当前的线程,直到另外一个线程运行结束
工具函数

pthread_equal(): 对两个线程的线程标识号进行比较
pthread_detach(): 分离线程
pthread_self(): 查询线程自身线程标识

**补充知识**   void *() &void* ()void*()区别
他们三者根本没有区别,void指的是返回值为空,void * 指的是返回值是任何类型的指针。

  例子:注意编译加上**-lpthead**
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>

void printids(const char *s)
{
    pid_t pid;  // int
    pthread_t tid;
    pid = getpid(); //for the id of process
    tid = pthread_self();//查询线程自身线程标识号
    printf("%s pid %u tid %u (0x%x)\n", s, (unsigned int) pid,
            (unsigned int) tid, (unsigned int) tid);
}

void *thr_fn(void *arg)
{
    printids("new thread: ");
    return NULL;
}

int main(void)
{
    int err;
    pthread_t ntid;
    err = pthread_create(&ntid, NULL, thr_fn, NULL);// 注意线程的入口在的地方。
    if (err != 0)
        printf("can't create thread: %s\n", strerror(err));
    printids("main thread:");
    pthread_join(ntid,NULL);
}
其他操纵函数

pthread_create():创建一个线程
pthread_exit():终止当前线程
pthread_cancel():中断另外一个线程的运行
pthread_join()
int pthread_join(pthread_t thread, void **retval);
阻塞当前的线程,直到另外一个线程运行结束
retval: 用户定义的指针,用来存储被等待线程的返回值,NUll不用进行储存状态。
pthread_attr_init():初始化线程的属性
pthread_attr_setdetachstate():设置脱离状态的属性(决定这个线程在终止时是否可以被结合)
pthread_attr_getdetachstate():获取脱离状态的属性
pthread_attr_destroy():删除线程的属性
pthread_kill():向线程发送一个信号
int pthread_kill(pthread_t thread, int sig)。

#include<stdio.h>
#include<unistd.h>
#include<signal.h>
#include<pthread.h>
#include<time.h>
pthread_t tid;
sigset_t set;
void myfunc()
{
    printf("hello\n");
}
static void *mythread(void*p)//注意格式用来做create的入口指针
{
int signum;
while(1)
{
    sigwait(&set,&signum);
    if(SIGUSR1==signum)
    myfunc();
    if(SIGUSR2==signum)
    {
    printf("Iwillsleep2secondandexit\n");
    sleep(2);
    break;
    }
}
}
int    main()
{
    char tmp;
    void *status;
    sigemptyset(&set);
    sigaddset(&set,SIGUSR1);
    sigaddset(&set,SIGUSR2);
    sigprocmask(SIG_SETMASK,&set,NULL);
    pthread_create(&tid,NULL,mythread,NULL);
    while(1)
    {
        printf(":");
        scanf("%c",&tmp);
        if('a'==tmp)
        {
            pthread_kill(tid,SIGUSR1);//发送SIGUSR1,打印字符串。
        }
        else if('q'==tmp)
        {
            //发出SIGUSR2信号,让线程退出,如果发送SIGKILL,线程将直接退出。
            pthread_kill(tid,SIGUSR2);
            //等待线程tid执行完毕,这里阻塞。
            pthread_join(tid,&status);
            printf("finish\n");
            break;
        }
        else
            continue;
    }
    return 0;
}
调试问题总结

1,expected identifier before numeric constant
解决方式:原来是因为有其他模块定义了同名的的变量。太恶心了,报的错和实际的问题完全没有提示。
2error: name lookup of ‘j’ changed for ISO ‘for’ scoping [-fpermissive]

错误的原因: for循环中在初始化时同时定义的变量的作用域范围的一个问题。
ISO/ANSI C++ 把在此定义的变量的作用域范围限定在 for 循环体内,也就是说,在循环体之外这个变量是无效的。但是编译的时候可以加参数-fpermissive,就没有问题了。如果不加这个参数,直接把for中定义并初始化的变量,定义与初始化分离:
2 in C++98 ‘box1’ must be initialized by constructor, not by ‘{…}’请问这是什么意思?怎么改?
变量初始化的时候,需要使用括号(),或者还有另外一种方式就是通过使用codeblocks中的编译选项,添加c11即可。

线程互斥锁的学习
目的:为了保持线程之间的同步。
常用函数:phread_mutex_init,pthread_mutex_destroy,phtread_mutex_lock,pthread_mutex_unlock.分别对应锁的初始化,销毁,锁定和解锁的目标。
如何创建锁呢?
    答案就是需要初始化。两种方式,第一,静态方式。使用宏PTHREAD_MUTEXZ_INITIALIZATION,互斥所是一个pthread_mutex_t的结构体,而这个宏定义是一个结构常量。第二种方式呢?就是通过pthread_mutex_t的结构体,
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t * attr)。
锁的类型
    *PTHREAD_MUTEX_TIMED_NP*,这是缺省值,也就是普通锁。当一个线程加锁以后,其余请求锁的线程将形成一个等待队列,并在解锁后按优先级获得锁。这种锁策略保证了资源分配的公平性。
   PTHREAD_MUTEX_ERRORCHECK_NP,检错锁,如果同一个线程请求同一个锁,则返回EDEADLK,否则与PTHREAD_MUTEX_TIMED_NP类型动作相同。这样就保证当不允许多次加锁时不会出现最简单情况下的死锁。
   PTHREAD_MUTEX_ADAPTIVE_NP,适应锁,动作最简单的锁类型,仅等待解锁后重新竞争。

可以用
pthread_mutexattr_settype(pthread_mutexattr_t *attr , int type)
pthread_mutexattr_gettype(pthread_mutexattr_t *attr , int *type)

获取或设置锁的类型。

 锁的释放
调用pthread_mutex_destory之后,可以释放锁占用的资源,但这有一个前提上锁当前是没有被锁的状态。
 锁操作
对锁的操作主要包括加锁 pthread_mutex_lock()、解锁pthread_mutex_unlock()和测试加锁 pthread_mutex_trylock()三个。

  int pthread_mutex_lock(pthread_mutex_t *mutex)

  int pthread_mutex_unlock(pthread_mutex_t *mutex)

  int pthread_mutex_trylock(pthread_mutex_t *mutex)

  pthread_mutex_trylock()语义与pthread_mutex_lock()类似,不同的是在锁已经被占据时返回EBUSY而不是挂起等待
关于socket的几点说明:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值