linux创建的线程不无,POSIX线程的创建和取消

先看一个例子:pthread1.c

#if defined(WIN32)

#include   // void Sleep(DWORD ms)

#define SLEEP(ms) Sleep(ms)

#else if defined(LINUX)

#include    // unsigned int sleep(unsigned int)

#include 

#include 

#define SLEEP(ms) sleep(ms)

#endif

#include 

/** 作为线程入口的函数 */

void* print_message_function(void*ptr)

{

SLEEP(5);

char*message;

message = (char*) ptr;

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

returnNULL;

}

intmain(intargc,char* argv[])

{

pthread_t thread1, thread2;

char*message1 ="Thread 1";

char*message2 ="Thread 2";

intiret1, iret2;

// 成功创建线程时返回零

iret1 = pthread_create(&thread1, NULL, &print_message_function, (void*) message1);

iret2 = pthread_create(&thread2, NULL, &print_message_function, (void*) message2);

/* 等待两个线程结束 -- 同步

* 如果不同步,则有可能主线程的return先执行,导致子线程未完成任务而先完蛋

* 可以启用Sleep试试。

*/

pthread_join(thread1, NULL);

pthread_join(thread2, NULL);

printf("Thread 1 returns: %d\n", iret1);

printf("Thread 2 returns: %d\n", iret2);

return0;

}

在Linux下编译:    * C compiler: cc -lpthread pthread1.c

* C++ compiler: g++ -lpthread pthread1.c

结束线程的方法:    * pthread_exit

* 让函数自己返回

* exit 停止整个进程(当然包括所有的线程)

创建线程的函数原型:

intpthread_create(pthread_t *thread,

constpthread_attr_t * attr,

void* (*start_routine)(void*),

void*arg);

pthread_create 的第二个参数pthread_attr_t

struct pthread_attr_t

{

enum    新线程是否与进程中其它线程脱离同步

{

PTHREAD_CREATE_JOINABLE    [default]   可以在创建后用 pthread_detach 脱离同步

PTHREAD_CREATE_DETACHED                  不能用 pthread_join 来同步,退出时自行释放资源

} __detachstate;

enum    新线程的调用策略

{

SCHED_OTHER [default]    非实时

SCHED_RR                           实时,轮转法    - 仅对超级用户有效

SCHED_FIFO                        实时,先入先出    - 仅对超级用户有效

} __schedpolicy;

struct sched_param        在运行时用 pthread_setschedparam 更新。

{

int sched_priority    线程的运行优先级。当上面的 __schedpolicy 为“实时”时才有效。缺省是零。

} __schedparam;

enum

{

PTHREAD_EXPLICIT_SCHED [default]    显式指定调度策略和调度参数,即使用 attr 中的值

PTHREAD_INHERIT_SCHED                     继承调用者线程的值

} __inheritsched;

enum    线程间竞争CPU的范围

{

PTHREAD_SCOPE_SYSTEM [default]   目前Linux只实现了这一种

PTHREAD_SCOPE_PROCESS              仅与同进程的线程竞争

} __scope;

}

下面三个没用过

* guard size

* stack address (See unistd.h and bits/posix_opt.h _POSIX_THREAD_ATTR_STACKADDR)

* stack size (default minimum PTHREAD_STACK_SIZE set in pthread.h)

创建线程时,如果写成下面的样子,也是可以的。这属于精简模式,作为函数指针的传入参数是和上面等价的:iret1 = pthread_create( &thread1, NULL, print_message_function, (void*) message1);

等待其它线程停止int pthread_join(pthread_t th, void **thread_return);

* th - 调用线程变为挂起状态,等待线程退出。退出线程可用 pthread_exit() 或者 cancel 类线程函数。

* thread_return - 不置为NULL的话,可以传出返回值。

退出当前线程void pthread_exit(void *retval);

若要在退出时返回数据在retval指向的内存里,务必保证该内存不是在线程局部空间里,否则会随着线程退出而消失。

可以通过向某线程发送cancel请求而强制终止该线程。该线程置自己为"cancel"状态后,运行至取消点(cancelation point),才会退出。

POSIX标准规定的取消点:

- pthread_join()、pthread_testcancel()、pthread_cond_wait()、pthread_cond_timedwait()、sem_wait()、sigwait()

- read、write等会引起阻塞的系统调用

但pthread_cancel的手册页声称,由于LinuxThread库与C库结合得不好,因而目前C库函数都不是取消点。

不过,cancel信号会使线程从阻塞的系统调用中退出,并置EINTR错误码。所以可以把这样的系统调用作为取消点:

pthread_testcancel();

retcode = read(fd, buffer, length);

pthread_testcancel();

这样,可达到POSIX的要求。

与取消线程相关的函数

- int pthread_cancel (pthread_t th)    发送取消信号给线程。若成功返回零;失败则非零。发送成功并不意味着线程会终止。

- int pthread_setcancelstate (int state, int *oldstate)    设置本线程对cancel信号的反应。

enum

{

PTHREAD_CANCEL_ENABLE [default]   收到信号后置自己为取消状态

PTHREAD_CANCEL_DISABLE                 忽略cancel信号,继续运行

} state

- int pthread_setcanceltype (int type int *oldtype)

enum

{

PTHREAD_CANCEL_DEFERRED [default]        收到cancel信号后继续运行,到达取消点时退出

PTHREAD_CANCEL_ASYNCHRONOUS           立即退出

} type    当上面的state为 PTHREAD_CANCEL_ENABLE 时该变量才有效。

- void pthread_testcancel (void)

检查本线程是否处于取消状态,若是,立刻退出。

#ifdef WIN32

#include 

#define SLEEP(ms) Sleep(ms)

#else if defined(LINUX)

#include 

#define SLEEP(ms) sleep(ms)

#endif

#include 

#include 

staticints_nThreadResult = 0;

void* theThread(void* param)

{

intcount = 0;

while(count 

{

printf("[Child] looping\n");

pthread_testcancel();

SLEEP(1);

count ++;

}

s_nThreadResult = 1;

pthread_exit(&s_nThreadResult);

returnNULL;

}

intmain(intargc,char* argv[])

{

intrc = 0;

pthread_t tid;

rc = pthread_create(&tid, NULL, &theThread, NULL);

assert(rc == 0 &&"pthread_create");

SLEEP(3);

// 若启用下面代码,则子线程提前返回

//rc = pthread_cancel(tid);

assert(rc == 0 &&"pthread_cancel");

// 阻塞自己,等待子线程返回

void* status = NULL;

rc = pthread_join(tid, &status);

assert(rc == 0 &&"pthread_join", rc);

// 若子线程是被取消从而结束的,则无返回值

if(status != PTHREAD_CANCELED && status != NULL)

{

printf("Returned value from thread: %d\n", *(int*)status);

}

return0;

}0b1331709591d260c1c78e86d0c51c18.png

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值