POSIX之Thread

2022-12-05 15:54:13 浏览数 (1)

POSIX - Portable Operating System Interface of UNIX定义了操作系统为应用程序提供的接口标准。

今天看一看Posix针对Thread(线程)定义的几个基本API

pthread_create()与pthread_self()

代码语言:javascript复制
/*
 * 使用属性pAttr创建线程
 * 成功后将线程ID存入pThread
 * 线程入口为pEntry, 其入参为pArg
 */
int pthread_create
    (
    pthread_t *pThread,     /* Thread ID (out) */
    pthread_attr_t *pAttr,  /* Thread attributes object */
    void *(*pEntry)(void *),/* Entry function */
    void *pArg              /* Entry function argument */
    );
/*
 * 返回当前线程的ID
 * 如果调用者是VxWorks的Task, 则将其转换为POSIX线程
 */
pthread_t pthread_self();

写个例子

代码语言:javascript复制
/*
 * 版权所有  公众号  VxWorks567
 */
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

static void *subThread(void *arg)
{
    printf(" new thread: tid %#xn", (UINT32)pthread_self());
    return NULL;
    }

#ifdef _WRS_KERNEL
int testThread()
#else
int main()
#endif
{
    pthread_t id;
    pthread_create(&id, NULL, subThread, NULL);

    sleep(1);
    printf("main thread: tid %#xn", (UINT32)pthread_self());
    return OK;
    }

pthread_exit()与pthread_join()

代码语言:javascript复制
/*
 * 终止当前线程
 * 入参status为线程的返回值, 可供pthread_join()使用
 */
void pthread_exit
    (
    void *status
    );
/*
 * 阻塞当前线程,直到线程thread终止或取消
 * 线程thread必须是joinable状态
 *
 * 如果ppStatus不是NULL, 且pthread_join()成功返回,
 * 线程thread终止时的exit状态存于ppStatus
 */
int pthread_join
    (
    pthread_t thread,
    void **ppStatus
    );

写个例子

代码语言:javascript复制
/*
 * 版权所有  公众号  VxWorks567
 */
#include <stdio.h>
#include <pthread.h>

static void *subThread(void *arg)
{
    pthread_exit("byebye");
    return NULL;
    }

#ifdef _WRS_KERNEL
int testThread()
#else
int main()
#endif
{
    pthread_t id;
    void *pStatus;

    pthread_create(&id, NULL, subThread, NULL);
    pthread_join(id, &pStatus);
    printf("subThread: %sn", (char *)pStatus);
    return OK;
    }

如果线程不是正常exit,而是被取消或被VxWorks Task删除,则返回PTHREAD_CANCELED(-2)

代码语言:javascript复制
/*
 * 版权所有  公众号  VxWorks567
 */
#include <stdio.h>
#ifndef _WRS_KERNEL
#include <taskLib.h>
#endif
#include <pthread.h>

/*
#define PTHREAD_CANCELED    ((void *)-2)
*/

static void *subThread(void *arg)
{
    taskDelete(0);
    return NULL;
    }

#ifdef _WRS_KERNEL
int testThread()
#else
int main()
#endif
{
    pthread_t id;
    void *pStatus;

    pthread_create(&id, NULL, subThread, NULL);
    pthread_join(id, &pStatus);
    printf("subThread: %dn", (int)pStatus);
    return OK;
    }

如果pthread_join()操作的是当前线程,则返回EDEADLK(33)

代码语言:javascript复制
/*
 * 版权所有  公众号  VxWorks567
 */
#include <stdio.h>
#include <pthread.h>

/*
#define  EDEADLK    33
*/

#ifdef _WRS_KERNEL
int testThread()
#else
int main()
#endif
{
    int ret = pthread_join(pthread_self(), NULL);
    printf("pthread_join: %dn", ret);
    return OK;
    }

如果pthread_join()操作的线程已不存在或者正在执行exit操作,则返回ESRCH(3)

代码语言:javascript复制
/*
 * 版权所有  公众号  VxWorks567
 */
#include <stdio.h>
#include <pthread.h>

/*
#define ESRCH     3
*/

#ifdef _WRS_KERNEL
int testThread()
#else
int main()
#endif
{
    int ret = pthread_join(0, NULL);
    printf("pthread_join: %dn", ret);
    return OK;
    }

如果pthread_join()操作的线程已被执行过pthread_join(),则返回EINVAL(22)

代码语言:javascript复制
/*
 * 版权所有  公众号  VxWorks567
 */
#include <stdio.h>
#ifndef _WRS_KERNEL
#include <taskLib.h>
#endif
#include <pthread.h>

/*
#define EINVAL  22
*/

static void *subThread(void *arg)
{
    sleep(1);
    return NULL;
    }

static void threadWait(pthread_t id)
{
    int ret = pthread_join(id, NULL);
    printf("subThread: %dn", ret);
    }

#ifdef _WRS_KERNEL
int testThread()
#else
int main()
#endif
{
    pthread_t id;

    pthread_create(&id, NULL, subThread, NULL);
    taskSpawn(NULL, 100, 0, 0x2000, (FUNCPTR)threadWait, id, 0,0,0,0,0,0,0,0,0);
    taskSpawn(NULL, 100, 0, 0x2000, (FUNCPTR)threadWait, id, 0,0,0,0,0,0,0,0,0);
    sleep(2);
    return OK;
    }

pthread_detach()

代码语言:javascript复制
/*
 * 将线程thread置于detached状态.
 * 则,其它线程不能通过pthread_join()进行同步.
 */
int pthread_detach
    (
    pthread_t thread
    );

再执行pthread_join()操作则返回EINVAL(22)

代码语言:javascript复制
/*
 * 版权所有  公众号  VxWorks567
 */
#include <stdio.h>
#include <pthread.h>

/*
#define EINVAL  22
*/

static void *subThread(void *arg)
{
    sleep(1);
    return NULL;
    }

#ifdef _WRS_KERNEL
int testThread()
#else
int main()
#endif
{
    pthread_t id;
    int ret;

    pthread_create(&id, NULL, subThread, NULL);
    pthread_detach(id);
    ret = pthread_join(id, NULL);
    printf("subThread: %dn", ret);
    sleep(2);
    return OK;
    }

pthread_equal()

代码语言:javascript复制
/*
 * 测试两个线程是否相同
 * 相同则返回1, 否则返回0
 */
int pthread_equal
    (
    pthread_t t1,
    pthread_t t2
    );

pthread_once()

代码语言:javascript复制
/*
 * 此机制确保initFunc只执行一次
 */
int pthread_once
    (
    pthread_once_t *pOnceControl,
    void (*initFunc)(void)
    );

写个例子

代码语言:javascript复制
/*
 * 版权所有  公众号  VxWorks567
 */
#include <stdio.h>
#include <pthread.h>

static int data=0;
 
static pthread_once_t once = PTHREAD_ONCE_INIT;
 
void threadInit()
{
    data = -1;
    printf("Thread %#x initializes data: %dn", (UINT32)pthread_self(), data);
    }
 
void *subThread(void *arg)
{
    pthread_once(&once, &threadInit);

    data  ;
    printf("Thread %#x uses data: %dn", (UINT32)pthread_self(), data);

    pthread_exit(&data);
    return NULL;
    }
 
#ifdef _WRS_KERNEL
int testThread()
#else
int main()
#endif
{
    pthread_t tid1;
    pthread_t tid2;
    int *pData;

    pthread_create(&tid1, NULL, &subThread, NULL);
    pthread_join(tid1, (void **)&pData);
    printf("thread %#x returns data: %dn", (UINT32)tid1, *pData);

    pthread_create(&tid2, NULL, &subThread, NULL);
    pthread_join(tid2, (void **)&pData);
    printf("thread %#x returns data: %dn", (UINT32)tid2, *pData);
    return OK;
    }

0 人点赞