Cobalt(POSIX)线程管理服务。
int pthread_create(pthread_t *ptid_r, const pthread_attr_t *attr, void *(*start)(void *), void *arg)
创建新线程。
此服务在双内核配置中创建由 Cobalt 核心管理的线程。
新线程的属性取决于 attr
参数。如果 attr
为 NULL,则使用这些属性的默认值。
从 start
例程返回的效果与调用 pthread_exit()
并传递返回值相同。
参数:
start
的用户提供的不透明参数。返回值:
attr
无效;CONFIG_XENO_OPT_SYS_HEAPSZ
;inheritsched
设置为 PTHREAD_INHERIT_SCHED
,且调用线程不属于 Cobalt 接口。注意:
首次创建 Cobalt 线程时,libcobalt 会为 SIGSHADOW
信号安装一个内部处理程序。如果您之前为该信号安装了处理程序,则该处理程序将仅在 Xenomai 未发送 SIGSHADOW
时被调用。
但是,如果之后安装了应用程序定义的 SIGSHADOW
处理程序,覆盖了 libcobalt 处理程序,则新处理程序需要在进入时调用 cobalt_sigshadow_handler()
。此例程对于每次由 Cobalt 核心发出的 SIGSHADOW
返回非零值。如果返回零,则应用程序定义的处理程序应处理该信号。
int cobalt_sigshadow_handler(int sig, siginfo_t *si, void *ctxt);
您应使用 sigaction(2)
注册处理程序,并设置 SA_SIGINFO
标志。
标签:
thread-unrestricted
,switch-secondary
示例代码
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
// 线程要执行的函数
void* thread_function(void* arg) {
int thread_id = *((int*)arg);
printf("Thread%d is running\n", thread_id);
sleep(1); // 模拟一些工作
printf("Thread%d finished\n", thread_id);
return NULL;
}
int main() {
pthread_t threads[5]; // 创建5个线程
int thread_ids[5]; // 用于存储线程ID
for (int i = 0; i < 5; i++) {
thread_ids[i] = i; // 设置线程ID
// 创建线程
if (pthread_create(&threads[i], NULL, thread_function, &thread_ids[i]) != 0) {
perror("pthread_create");
return 1;
}
}
// 等待所有线程结束
for (int i = 0; i < 5; i++) {
pthread_join(threads[i], NULL);
}
printf("Thread Work Finished\n");
return 0;
}
int pthread_join(pthread_t thread, void **ret_val)
等待指定线程终止。
如果 thread
正在运行且可连接,此服务将阻塞调用者,直到 thread
终止或分离。当 thread
终止时,调用者将被解除阻塞,并将其返回值存储在 ret_val
指向的地址中。
另一方面,如果 thread
已经完成执行,其先前收集的返回值将存储在 ret_val
指向的地址中,并且此服务将立即返回。
对于 Cobalt 线程,此服务是一个取消点:如果调用线程在调用此服务时被取消,则取消请求将被接受,并且 thread
仍然是可连接的。
多个同时调用 pthread_join()
指定相同运行目标线程的调用者将全部阻塞,直到目标线程终止。
参数:
返回值:
thread
无效;thread
已分离;标签:
xthread-only
,switch-secondary
,switch-primary
示例代码
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
// 线程要执行的函数
void* thread_function(void* arg) {
int thread_id = *((int*)arg);
printf("Thread%d is running\n", thread_id);
sleep(1); // 模拟一些工作
printf("Thread%d finished\n", thread_id);
return NULL;
}
int main() {
pthread_t threads[5]; // 创建5个线程
int thread_ids[5]; // 用于存储线程ID
for (int i = 0; i < 5; i++) {
thread_ids[i] = i; // 设置线程ID
// 创建线程
if (pthread_create(&threads[i], NULL, thread_function, &thread_ids[i]) != 0) {
perror("pthread_create");
return 1;
}
}
// 等待所有线程结束
for (int i = 0; i < 5; i++) {
pthread_join(threads[i], NULL);
}
printf("Thread Work Finished\n");
return 0;
}
int pthread_kill(pthread_t thread, int sig)
向线程发送信号。
此服务向 Cobalt 线程 thread
(通过 pthread_create()
创建)发送信号 sig
。如果 sig
为零,此服务将检查线程 thread
的存在性,但不会发送任何信号。
参数:
返回值:
sig
是无效的信号编号;thread
是无效的线程标识符。标签:
thread-unrestricted
,switch-primary
示例代码
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
#include <cobalt/wrappers.h>
pthread_t thread1,thread2;
void *thread_function1(void *arg) {
// 初始化信号集
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGQUIT);
int sig;
printf("Thread1 started, waiting for signal...\n");
// 阻塞并等待信号
if(sigwait(&set,&sig) == 0)
{
printf("thread1 get SIGQUIT signal\n");
}else{
perror("sigwait");
}
printf("Thread1 finished.\n");
return NULL;
}
void *thread_function2(void *arg) {
// 初始化信号集
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGUSR1);
int sig;
printf("Thread2 started, waiting for signal...\n");
// 阻塞并等待信号
if(sigwait(&set,&sig) == 0)
{
printf("thread2 get SIGUSR1 signal\n");
}else{
perror("sigwait");
}
printf("Thread2 finished.\n");
return NULL;
}
int main() {
// 创建线程
if (pthread_create(&thread1, NULL, thread_function1, NULL) != 0) {
perror("Failed to create thread");
return 1;
}
if (pthread_create(&thread2, NULL, thread_function2, NULL) != 0) {
perror("Failed to create thread");
return 1;
}
sleep(1);
// 发送信号给Thread1
pthread_kill(thread1, SIGQUIT);
// 发送信号给Thread2
pthread_kill(thread2, SIGUSR1);
// 等待线程结束
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
return 0;
}
int pthread_setmode_np(int clrmask, int setmask, int *mode_r)
设置当前线程的模式。
此服务设置调用线程的模式,影响其在特定情况下的行为。clrmask
和 setmask
是两个模式位掩码,分别由 pthread_setmode_np()
清除和设置。
PTHREAD_DISABLE_LOCKBREAK
,线程仍可能阻塞,暂时释放锁,在这种情况下,当线程恢复执行时,锁将自动重新获取。SIGDEBUG
信号(源自 Linux)。setmask
中传递,以将当前 Cobalt 线程切换到其首选的运行模式。此服务是 Cobalt 接口的非可移植扩展。
参数:
mode_r
必须是一个指向内存位置的指针,成功时将写入先前的活动模式位集合。返回值:
clrmask
或 setmask
中的某些位无效。注意:
clrmask
和 setmask
设置为零会导致无操作,仅在 mode_r
是有效地址时返回先前的模式。注意:
PTHREAD_CONFORMING
很可能是无用的,甚至会引入纯粹的开销。标签:
xthread-only
,switch-primary
示例代码
#include <stdio.h>
#include <stdlib.h>
#include <cobalt/sched.h>
#include <cobalt/pthread.h>
#include <unistd.h>
#include <string.h>
void* thread_function(void* arg) {
int thread_id = *(int*)arg;
printf("Thread %d is running...\n", thread_id);
sleep(2);
return NULL;
}
int main() {
pthread_t thread1, thread2;
int thread_id1 = 1, thread_id2 = 2;
// 创建第一个线程
if (pthread_create(&thread1, NULL, thread_function, &thread_id1) != 0) {
perror("Failed to create thread 1");
return 1;
}
// 创建第二个线程
if (pthread_create(&thread2, NULL, thread_function, &thread_id2) != 0) {
perror("Failed to create thread 2");
return 1;
}
int mode = 0;
// 设置当前线程的模式
if (pthread_setmode_np(PTHREAD_WARNSW|PTHREAD_LOCK_SCHED, 0, &mode) != 0) {
perror("pthread_setmode_np");
return 1;
}
// 等待线程结束
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
// 取消线程模式
if (pthread_setmode_np(0, PTHREAD_WARNSW|PTHREAD_LOCK_SCHED, &mode) != 0) {
perror("pthread_setmode_np");
return 1;
}
printf("Both threads have finished execution.\n");
return 0;
}
int pthread_setname_np(pthread_t thread, const char *name)
设置线程名称。
此服务将线程 thread
的名称设置为 name
。该名称用于在 /proc/xenomai/sched
中显示信息。
此服务是 Cobalt 接口的非可移植扩展。
参数:
返回值:
thread
无效。标签:
xthread-only
示例代码
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <unistd.h>
void* thread_function(void* arg) {
printf("Thread %ld is running...\n", (long)arg);
sleep(10);
return NULL;
}
int main() {
pthread_t thread;
const char* thread_name = "Sinsegye";
// 创建线程
if (pthread_create(&thread, NULL, thread_function, (void*)1) != 0) {
perror("Failed to create thread");
return 1;
}
// 设置线程名称
if (pthread_setname_np(thread, thread_name) != 0) {
perror("Failed to set thread name");
return 1;
}
// 等待线程结束
pthread_join(thread, NULL);
printf("Thread has finished execution.\n");
return 0;
}