┌──(root㉿Executor)-[/mnt/c/Users/86135/desktop/pthread] └─# gcc main.c -o main
┌──(root㉿Executor)-[/mnt/c/Users/86135/desktop/pthread] └─# ./main in main,tid=139945163630400 in func,tid=139945163630400
每次运行,tid都是不同的数值,但是main和func两个函数中打印的tid都是相同的
因为func不是新线程执行的,它仍然是main线程执行的.
创建线程pthread_create
pthread.h
1 2 3 4 5 6 7 8
/* Create a new thread, starting with execution of START-ROUTINE getting passed ARG. Creation attributed come from ATTR. The new handle is stored in *NEWTHREAD. */ externintpthread_create( pthread_t *__restrict __newthread, __const pthread_attr_t *__restrict __attr, void *(*__start_routine) (void *), void *__restrict __arg)//到此函数参数表已经结束,后面是Function Attributes修饰 __THROW __nonnull((1, 3));
创建一个新线程,从START_ROUTINE函数,带着ARG参数
开始执行.
线程函数的参数只能有一个,是一个
以参数ATTR为线程属性
新的线程句柄以参数NEWTHREAD返回
如果创建新线程成功则函数返回0,否则返回数字代表错误原因
关于参数的__restrict修饰符
__restrict
Like the __declspec ( restrict
) modifier, the __restrict
keyword (two leading underscores '_') indicates that a symbol isn't
aliased in the current scope
causes the compiler to check that, in calls to
my_memcpy, arguments dest and src are non-null. If the
compiler determines that a null pointer is passed in an argument slot
marked as non-null, and the -Wnonnull option is enabled, a warning is
issued. The compiler may also choose to make optimizations based on the
knowledge that certain function arguments will not be null.
The nothrow attribute is used to inform the compiler
that a function cannot throw an exception. For example, most functions
in the standard C library can be guaranteed not to throw an exception
with the notable exceptions of qsort and
bsearch that take function pointer arguments. The
nothrow attribute is not implemented in GCC versions
earlier than 3.3.
nothrow属性用来通知编译器,函数不会抛出异常
比如,C标准库中的大多数函数都保证不会抛出qsort和bsearch使用函数指针作为参数的错误;
在GCC3.3之前没有该属性
1
leaf
Calls to external functions with this attribute must return to the
current compilation unit only by return or by exception handling. In
particular, leaf functions are not allowed to call callback function
passed to it from the current compilation unit or directly call
functions exported by the unit or longjmp into the unit. Leaf function
might still call functions from other compilation units and thus they
are not necessarily leaf in the sense that they contain no function
calls at all.
The attribute is intended for library functions to improve dataflow
analysis. The compiler takes the hint that any data not escaping the
current compilation unit can not be used or modified by the leaf
function. For example, the sin function is a leaf function,
but qsort is not.
Note that leaf functions might invoke signals and signal handlers
might be defined in the current compilation unit and use static
variables. The only compliant way to write such a signal handler is to
declare such variables volatile.
The attribute has no effect on functions defined within the current
compilation unit. This is to allow easy merging of multiple compilation
units into one, for example, by using the link time optimization. For
this reason the attribute is not allowed on types to annotate indirect
calls.
┌──(root㉿Executor)-[/mnt/c/Users/86135/desktop/pthread] └─# gcc main.c -o main -lpthread
┌──(root㉿Executor)-[/mnt/c/Users/86135/desktop/pthread] └─# ./main in main,tid1=140685510317888 in main,tid2=140685510313536 in func,tid=140685510313536
/* Terminate calling thread. The registered cleanup handlers are called via exception handling so we cannot mark this function with __THROW.*/ externvoidpthread_exit(void *__retval) __attribute__((__noreturn__));
终止线程
清理程序以异常处理进行,因此我们不能将该函数标记为__THROW
返回值通过指针参数void *__retval传递
杀死对等线程pthread_cancel
1 2
/* Cancel THREAD immediately or at the next possibility. */ externintpthread_cancel(pthread_t __th);
/* Make calling thread wait for termination of the thread TH. The exit status of the thread is stored in *THREAD_RETURN, if THREAD_RETURN is not NULL. This function is a cancellation point and therefore not marked with __THROW. */ externintpthread_join(pthread_t __th, void **__thread_return);
┌──(kali㉿Executor)-[/mnt/c/Users/86135/desktop/pthread] └─$ ./main thread 140127873893952 created in func,tid=140127873893952 thread 140127873893952 joined thread 140127873893952 created main exit
/* Indicate that the thread TH is never to be joined with PTHREAD_JOIN. The resources of TH will therefore be freed immediately when it terminates, instead of waiting for another thread to perform PTHREAD_JOIN on it. */ externintpthread_detach(pthread_t __th) __THROW;
pthread_detach函数表明,TH线程将永远不会"加入"调用线程
因此当TH线程结束时,其资源将会被立刻回收,而不必再等待被对等线程调用pthread_join回收
初始化线程pthread_once
1 2 3 4 5 6 7 8 9 10
/* Guarantee that the initialization function INIT_ROUTINE will be called only once, even if pthread_once is executed several times with the same ONCE_CONTROL argument. ONCE_CONTROL must point to a static or extern variable initialized to PTHREAD_ONCE_INIT. The initialization functions might throw exception which is why this function is not marked with __THROW. */ externintpthread_once(pthread_once_t *__once_control, void (*__init_routine) (void)) __nonnull((1, 2));
┌──(kali㉿Executor)-[/mnt/c/Users/86135/desktop/pthread] └─$ gcc -O0 main.c -o main -lpthread
┌──(kali㉿Executor)-[/mnt/c/Users/86135/desktop/pthread] └─$ ./main in main,tid=140195300874048,&global=0x558b84485048 in func,tid=140195300869696,&global=0x558b84485048,&local_in_func=0x7f81c31b7e48,&static_in_func=0x558b8448504c in func,tid=140195292476992,&global=0x558b84485048,&local_in_func=0x7f81c29b6e48,&static_in_func=0x558b8448504c tid=140195300869696 exit tid=140195292476992 exit
/* Initialize semaphore object SEM to VALUE. If PSHARED then share it with other processes. */ externintsem_init(sem_t *__sem, int __pshared, unsignedint __value) __THROW;
信号量以指针sem_t *__sem传参,
int __pshared总是0,
unsigend int __value表示信号量的初始值(最大值)
PV操作sem_wait&sem_post
1 2 3 4 5 6 7
/* Wait for SEM being posted. This function is a cancellation point and therefore not marked with __THROW. */ externintsem_wait(sem_t *__sem); /* Post SEM. */ externintsem_post(sem_t *__sem) __THROW;
typedefstruct{ int *buf; int n; int front; int rear; }Queue; //普通队列,不同步 voidqueue_init(Queue*,int);//初始化一个队列 voidqueue_destroy(Queue*); intempty(Queue*); intfull(Queue*); voidpush(Queue*,int); intpop(Queue*); intlength(Queue*);