学校网站建设分析,文化展厅的设计方案,电商设计和ui设计哪个前景比较好,常州营销型网站建设C 信号处理
C 信号处理
信号是由操作系统传给进程的中断#xff0c;会提早终止一个程序。在 UNIX、LINUX、Mac OS X 或 Windows 系统上#xff0c;可以通过按 CtrlC 产生中断。
有些信号不能被程序捕获#xff0c;但是下表所列信号可以在程序中捕获#xff0c;并可以基于…C 信号处理
C 信号处理
信号是由操作系统传给进程的中断会提早终止一个程序。在 UNIX、LINUX、Mac OS X 或 Windows 系统上可以通过按 CtrlC 产生中断。
有些信号不能被程序捕获但是下表所列信号可以在程序中捕获并可以基于信号采取适当的动作。这些信号是定义在 C 头文件 csignal 中。
信号描述SIGABRT程序的异常终止如调用 abort。SIGFPE错误的算术运算比如除以零或导致溢出的操作。SIGILL检测非法指令。SIGINT接收到交互注意信号。SIGSEGV非法访问内存。SIGTERM发送到程序的终止请求。
signal() 函数
C 信号处理库提供了 signal 函数用来捕获突发事件。以下是 signal() 函数的语法
void (*signal (int sig, void (*func)(int)))(int); 这个函数接收两个参数第一个参数是一个整数代表了信号的编号第二个参数是一个指向信号处理函数的指针。
让我们编写一个简单的 C 程序使用 signal() 函数捕获 SIGINT 信号。不管您想在程序中捕获什么信号您都必须使用 signal 函数来注册信号并将其与信号处理程序相关联。看看下面的实例
#include iostream
#include csignal
#include unistd.husing namespace std;void signalHandler( int signum )
{cout Interrupt signal ( signum ) received.\n;// 清理并关闭// 终止程序 exit(signum); }int main ()
{// 注册信号 SIGINT 和信号处理程序signal(SIGINT, signalHandler); while(1){cout Going to sleep.... endl;sleep(1);}return 0;
} 当上面的代码被编译和执行时它会产生下列结果
Going to sleep....
Going to sleep....
Going to sleep....现在按 CtrlC 来中断程序您会看到程序捕获信号程序打印如下内容并退出
Going to sleep....
Going to sleep....
Going to sleep....
Interrupt signal (2) received.raise() 函数
您可以使用函数 raise() 生成信号该函数带有一个整数信号编号作为参数语法如下
int raise (signal sig);在这里sig 是要发送的信号的编号这些信号包括SIGINT、SIGABRT、SIGFPE、SIGILL、SIGSEGV、SIGTERM、SIGHUP。以下是我们使用 raise() 函数内部生成信号的实例
#include iostream
#include csignalusing namespace std;void signalHandler( int signum )
{cout Interrupt signal ( signum ) received.\n;// 清理并关闭// 终止程序 exit(signum); }int main ()
{int i 0;// 注册信号 SIGINT 和信号处理程序signal(SIGINT, signalHandler); while(i){cout Going to sleep.... endl;if( i 3 ){raise( SIGINT);}sleep(1);}return 0;
} 当上面的代码被编译和执行时它会产生下列结果并会自动退出
Going to sleep....
Going to sleep....
Going to sleep....
Interrupt signal (2) received.C 多线程
C 多线程
多线程是多任务处理的一种特殊形式多任务处理允许让电脑同时运行两个或两个以上的程序。在一般情况下有两种类型的多任务处理基于进程和基于线程。
基于进程的多任务处理处理的是程序的并发执行。基于线程的多任务处理的是同一程序的片段的并发执行。
多线程程序包含可以同时运行的两个或多个部分。这样的程序中的每个部分称为一个线程每个线程定义了一个单独的执行路径。
C 不包含多线程应用程序的任何内置支持。相反它完全依赖于操作系统来提供此功能。
本教程假设您使用的是 Linux 操作系统我们要使用 POSIX 编写多线程 C 程序。POSIX Threads 或 Pthreads 提供的 API 可在多种类 Unix POSIX 系统上可用比如 FreeBSD、NetBSD、GNU/Linux、Mac OS X 和 Solaris。
创建线程
有下面的例程我们可以用它来创建一个 POSIX 线程
#include pthread.h
pthread_create (thread, attr, start_routine, arg) 在这里pthread_create 创建一个新的线程并让它可执行。这个例程可在代码内的任何地方被调用任意次数。下面是关于参数的说明
参数描述thread一个不透明的、唯一的标识符用来标识例程返回的新线程。attr一个不透明的属性对象可以被用来设置线程属性。您可以指定线程属性对象也可以使用默认值 NULL。start_routineC 例程一旦线程被创建就会执行。arg一个可能传递给 start_routine 的参数。它必须通过把引用作为指针强制转换为 void 类型进行传递。如果没有传递参数则使用 NULL。
一个进程可以创建的最大线程数是依赖于实现的。线程一旦被创建就是同等的而且可以创建其他线程。线程之间没有隐含层次或依赖。
终止线程
有下面的例程我们可以用它来终止一个 POSIX 线程
#include pthread.h
pthread_exit (status) 在这里pthread_exit 用于显式地退出一个线程。通常情况下pthread_exit() 例程是在线程完成工作后无需继续存在时被调用。
如果 main() 是在它所创建的线程之前结束并通过 pthread_exit() 退出那么其他线程将继续执行。否则它们将在 main() 结束时自动被终止。
实例
这个简单的实例代码使用 pthread_create() 例程创建了 5 个线程。每个线程打印一个 Hello World! 消息然后调用 pthread_exit() 终止线程。
#include iostream
// 必须的头文件是
#include pthread.husing namespace std;#define NUM_THREADS 5// 线程的运行函数
void* say_hello(void* args)
{cout Hello w3cschool endl;
}int main()
{// 定义线程的 id 变量多个变量使用数组pthread_t tids[NUM_THREADS];for(int i 0; i NUM_THREADS; i){//参数依次是创建的线程id线程参数调用的函数传入的函数参数int ret pthread_create(tids[i], NULL, say_hello, NULL);if (ret ! 0){cout pthread_create error: error_code ret endl;}}//等各个线程退出后进程才结束否则进程强制结束了线程可能还没反应过来pthread_exit(NULL);
} 使用 -lpthread 库编译下面的程序 $ g test.cpp -lpthread -o test.o 现在执行程序将产生下列结果 $ ./test.o
Hello w3cschool
Hello w3cschool
Hello w3cschool
Hello w3cschool
Hello w3cschool 以下简单的实例代码使用 pthread_create() 函数创建了 5 个线程并接收传入的参数。每个线程打印一个 Hello w3cschool 消息并输出接收的参数然后调用 pthread_exit() 终止线程。
//文件名test.cpp#include iostream
#include cstdlib
#include pthread.husing namespace std;#define NUM_THREADS 5void *PrintHello(void *threadid)
{ // 对传入的参数进行强制类型转换由无类型指针变为整形数指针然后再读取int tid *((int*)threadid);cout Hello w3cschool线程 ID, tid endl;pthread_exit(NULL);
}int main ()
{pthread_t threads[NUM_THREADS];int indexes[NUM_THREADS];// 用数组来保存i的值int rc;int i;for( i0; i NUM_THREADS; i ){ cout main() : 创建线程, i endl;indexes[i] i; //先保存i的值// 传入的时候必须强制转换为void* 类型即无类型指针 rc pthread_create(threads[i], NULL, PrintHello, (void *)(indexes[i]));if (rc){cout Error:无法创建线程, rc endl;exit(-1);}}pthread_exit(NULL);
}
现在编译并执行程序将产生下列结果
$ g test.cpp -lpthread -o test.o
$ ./test.o
main() : 创建线程, 0
main() : 创建线程, 1
main() : 创建线程, 2
main() : 创建线程, 3
main() : 创建线程, 4
Hello w3cschool! 线程 ID, 4
Hello w3cschool! 线程 ID, 3
Hello w3cschool! 线程 ID, 2
Hello w3cschool! 线程 ID, 1
Hello w3cschool! 线程 ID, 0 向线程传递参数
这个实例演示了如何通过结构传递多个参数。您可以在线程回调中传递任意的数据类型因为它指向 void如下面的实例所示
#include iostream
#include cstdlib
#include pthread.husing namespace std;#define NUM_THREADS 5struct thread_data{int thread_id;char *message;
};void *PrintHello(void *threadarg)
{struct thread_data *my_data;my_data (struct thread_data *) threadarg;cout Thread ID : my_data-thread_id ;cout Message : my_data-message endl;pthread_exit(NULL);
}int main ()
{pthread_t threads[NUM_THREADS];struct thread_data td[NUM_THREADS];int rc;int i;for( i0; i NUM_THREADS; i ){cout main() : creating thread, i endl;td[i].thread_id i;td[i].message This is message;rc pthread_create(threads[i], NULL,PrintHello, (void *)td[i]);if (rc){cout Error:unable to create thread, rc endl;exit(-1);}}pthread_exit(NULL);
} 当上面的代码被编译和执行时它会产生下列结果 $ g -Wno-write-strings test.cpp -lpthread -o test.o
$ ./test.o
main() : creating thread, 0
main() : creating thread, 1
main() : creating thread, 2
main() : creating thread, 3
main() : creating thread, 4
Thread ID : 3 Message : This is message
Thread ID : 2 Message : This is message
Thread ID : 0 Message : This is message
Thread ID : 1 Message : This is message
Thread ID : 4 Message : This is message 连接和分离线程
有以下两个例程我们可以用它们来连接或分离线程
pthread_join (threadid, status)
pthread_detach (threadid) pthread_join() 子例程阻碍调用例程直到指定的 threadid 线程终止为止。当创建一个线程时它的某个属性会定义它是否是可连接的joinable或可分离的detached。只有创建时定义为可连接的线程才可以被连接。如果线程创建时被定义为可分离的则它永远也不能被连接。
这个实例演示了如何使用 pthread_join() 例程来等待线程的完成。
#include iostream
#include cstdlib
#include pthread.h
#include unistd.husing namespace std;#define NUM_THREADS 5void *wait(void *t)
{int i;long tid;tid (long)t;sleep(1);cout Sleeping in thread endl;cout Thread with id : tid ...exiting endl;pthread_exit(NULL);
}int main ()
{int rc;int i;pthread_t threads[NUM_THREADS];pthread_attr_t attr;void *status;// 初始化并设置线程为可连接的joinablepthread_attr_init(attr);pthread_attr_setdetachstate(attr, PTHREAD_CREATE_JOINABLE);for( i0; i NUM_THREADS; i ){cout main() : creating thread, i endl;rc pthread_create(threads[i], NULL, wait, (void *)i );if (rc){cout Error:unable to create thread, rc endl;exit(-1);}}// 删除属性并等待其他线程pthread_attr_destroy(attr);for( i0; i NUM_THREADS; i ){rc pthread_join(threads[i], status);if (rc){cout Error:unable to join, rc endl;exit(-1);}cout Main: completed thread id : i ;cout exiting with status : status endl;}cout Main: program exiting. endl;pthread_exit(NULL);
} 当上面的代码被编译和执行时它会产生下列结果 main() : creating thread, 0
main() : creating thread, 1
main() : creating thread, 2
main() : creating thread, 3
main() : creating thread, 4
Sleeping in thread
Thread with id : 4 ...exiting
Sleeping in thread
Thread with id : 3 ...exiting
Sleeping in thread
Thread with id : 2 ...exiting
Sleeping in thread
Thread with id : 1 ...exiting
Sleeping in thread
Thread with id : 0 ...exiting
Main: completed thread id :0 exiting with status :0
Main: completed thread id :1 exiting with status :0
Main: completed thread id :2 exiting with status :0
Main: completed thread id :3 exiting with status :0
Main: completed thread id :4 exiting with status :0
Main: program exiting.