c语言编程进程同步控制,UNIX环境C语言编程(18)-线程控制

1、线程属性

int

pthread_attr_init

(

pthread_attr_t

*

attr

);

int

pthread_attr_destroy

(

pthread_attr_t

*

attr

);

涉及分离状态、堆栈起始地址、堆栈大小、警戒区域大小、并发级别

设置

/

获取分离状态

int

pthread_attr_getdetachstate

(

const

pthread_attr_t

*restrict

attr

,

int

*

detachstate

);

int

pthread_attr_setdetachstate

(

pthread_attr_t

*

attr

,

int

detachstate

);

2、同步对象的属性

互斥体属性

允许一个互斥体在多个

进程

间共享

int

pthread_mutexattr_getpshared

(

const

pthread_mutexattr_t

*restrict

attr

,

int

*restrict

pshared

);

int

pthread_mutexattr_setpshared

(

pthread_mutexattr_t

*

attr

,

int

pshared

);

int

pthread_mutexattr_gettype

(

const

pthread_mutexattr_t

*restrict

attr

,

int

*restrict type);

int

pthread_mutexattr_settype

(

pthread_mutexattr_t

*

attr

,

int

type);

对于

PTHREAD_MUTEX_RECURSIVE

类型,允许一个互斥体被同一个线程多次加锁

读写锁属性:

允许一个读写锁在多个

进程

间共享

条件变量属性:

允许一个条件变量在多个

进程

间共享

3、可重入-线程安全

指函数可以同时被多个线程安全的调用

注意不要在函数内使用静态数据

4、特定于线程的数据

又称为线程私有数据

创建一个

key

,确保只能被调用一次,正确的调用序列

void destructor(void *);

pthread_key_t key;

pthread_once_t init_done = PTHREAD_ONCE_INIT;

void

thread_init(void)

{

err = pthread_key_create(&key, destructor);

}

int

threadfunc(void *arg)

{

pthread_once(&init_done, thread_init);

...

}

key

绑定地址

void *

pthread_getspecific

(

pthread_key_t

key);

int

pthread_setspecific

(

pthread_key_t

key,

const

void *value);

5、cancel选项

设置

cancel

状态,允许

cancel

或禁止

cancel

int

pthread_setcancelstate

(

int

state,

int

*

oldstate

);

设置

cancel

类型,延迟

cancel

或立即

cancel

int

pthread_setcanceltype

(

int

type,

int

*

oldtype

);

缺省为延迟

cancel

cancel

请求被暂时挂起,只有线程执行到某些特定的函数时,才能被

cancel

void

pthread_testcancel

(void);//

增加一个

cancel

立即

cancel

:允许线程被随时终止

6、线程与信号

每个线程有自己的信号掩码,但是信号的处理动作是整个进程共享的

信号只递交给单个线程,对于硬件故障或定时器信号,递交给对应的线程;其它信号,递交给一个随机的线程

改变线程的信号屏蔽

int

pthread_sigmask

(

int

how,

const

sigset_t

*restrict set,

sigset_t

*restrict

oset

);

int

sigwait

(

const

sigset_t

*restrict set,

int

*restrict

signop

);//

等待信号发生

int

pthread_kill

(

pthread_t

thread,

int

signo

);//

想线程发送信号

创建一个线程,专职处理信号

#include

#include

#include

#include

#include

int quitflag; /* set nonzero by thread */

sigset_t mask;

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

pthread_cond_t wait = PTHREAD_COND_INITIALIZER;

void *thr_fn(void *arg)

{

int err, signo;

for (;;)

{

err = sigwait(&mask, &signo);

if (err != 0) printf("%d, %s\n", err, "sigwait failed");

switch (signo)

{

case SIGINT:

printf("\ninterrupt\n");

break;

case SIGQUIT:

pthread_mutex_lock(&lock);

quitflag = 1;

pthread_mutex_unlock(&lock);

pthread_cond_signal(&wait);

return(0);

default:

printf("unexpected signal %d\n", signo);

exit(1);

}

}

}

int main(void)

{

int err;

sigset_t oldmask;

pthread_t tid;

sigemptyset(&mask);

sigaddset(&mask, SIGINT);

sigaddset(&mask, SIGQUIT);

if ((err = pthread_sigmask(SIG_BLOCK, &mask, &oldmask)) != 0)

printf("%d, %s\n", err, "SIG_BLOCK error");

err = pthread_create(&tid, NULL, thr_fn, 0);

if (err != 0) printf("%d, %s\n", err, "can't create thread");

pthread_mutex_lock(&lock);

while (quitflag == 0)

pthread_cond_wait(&wait, &lock);

pthread_mutex_unlock(&lock);

/* SIGQUIT has been caught and is now blocked; do whatever */

quitflag = 0;

/* reset signal mask which unblocks SIGQUIT */

if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)

perror("SIG_SETMASK error");

exit(0);

}

7、线程与fork

fork

后,子进程中只存在一个线程,同时继承了互斥体、读写锁、条件变量

子进程需要清理继承的同步对象

int

pthread_atfork

(void (*prepare)(void), void (*parent)(void), void (*child)(void));

#include

#include

#include

#include

pthread_mutex_t lock1 = PTHREAD_MUTEX_INITIALIZER;

pthread_mutex_t lock2 = PTHREAD_MUTEX_INITIALIZER;

void prepare(void)

{

printf("preparing locks...\n");

pthread_mutex_lock(&lock1);

pthread_mutex_lock(&lock2);

}

void parent(void)

{

printf("parent unlocking locks...\n");

pthread_mutex_unlock(&lock1);

pthread_mutex_unlock(&lock2);

}

void child(void)

{

printf("child unlocking locks...\n");

pthread_mutex_unlock(&lock1);

pthread_mutex_unlock(&lock2);

}

void *thr_fn(void *arg)

{

printf("thread started...\n");

pause();

return(0);

}

int main(void)

{

int err;

pid_t pid;

pthread_t tid;

#if defined(BSD) || defined(MACOS)

printf("pthread_atfork is unsupported\n");

#else

if ((err = pthread_atfork(prepare, parent, child)) != 0)

printf("%d, %s\n", err, "can't install fork handlers");

err = pthread_create(&tid, NULL, thr_fn, 0);

if (err != 0) printf("%d, %s\n", err, "can't create thread");

sleep(2);

printf("parent about to fork...\n");

if ((pid = fork()) < 0)

perror("fork failed");

else if (pid == 0) /* child */

printf("child returned from fork\n");

else /* parent */

printf("parent returned from fork\n");

#endif

exit(0);

}

8、线程与I/O

pread

()

pwrite

()

函数在多线程环境中非常有用,原子操作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值