stat,string,iconv,socket,sigprocmask,pthread_sigmask 亦凉 2022-08-06 10:17 67阅读 0赞 **stat,fstat,lstat: ** int stat(const char \*path, struct stat \*buf); int fstat(int fd, struct stat \*buf); int lstat(const char \*path, struct stat \*buf); struct stat \{ dev\_t st\_dev; /\* ID of device containing file \*/ ino\_t st\_ino; /\* inode number \*/ mode\_t st\_mode; /\* protection \*/ nlink\_t st\_nlink; /\* number of hard links \*/ uid\_t st\_uid; /\* user ID of owner \*/ gid\_t st\_gid; /\* group ID of owner \*/ dev\_t st\_rdev; /\* device ID (if special file) \*/ off\_t st\_size; /\* total size, in bytes \*/ blksize\_t st\_blksize; /\* blocksize for file system I/O \*/ blkcnt\_t st\_blocks; /\* number of 512B blocks allocated \*/ time\_t st\_atime; /\* time of last access \*/ time\_t st\_mtime; /\* time of last modification \*/ time\_t st\_ctime; /\* time of last status change \*/ \}; stat和lstat的区别:当文件是一个符号链接时,lstat返回的是该符号链接本身的信息;而stat返回的是该链接指向的文件的信息。 **string:** <string>文件中: size_type find_first_not_of (const charT* s, size_type pos = 0) const; 在pos 后搜索字符串,如果找到不匹配字符串s的任意字符 的话, 返回该位置;否则返回string::npos。 size_type find_first_of (const charT* s, size_type pos = 0) const; 与上相反 basic_string substr (size_type pos = 0, size_type len = npos) const; 返回在pos处开始,扩展长度为len的子串,或者直到字符串结尾。 pos等于字符串长度,则返回空串;pos大于字符串长度,抛出异常。 **iconv:** iconv\_open——申请一个字符集转换的描述符 \#include <iconv.h> iconv\_t iconv\_open(const char\* tocode,const char\* fromcode) 描述: iconv\_open()函数申请一个转换描述符,转换字符序列从编码fromcode到编码tocode 转换描述符包含转换状态,调用iconv\_open创建以后,转换状态处于初始状态,调用iconv函数以后改变转换描述符的转换状态,**(意味着转换描述符不能在多线程中同时使用)** 返回值: iconv\_open函数返回一个新申请的转换描述符,出错时,返回(iconv\_t)-1; iconv函数: size\_t iconv(iconv\_t cd,char \*\*inbuf,size\_t \*inbytesleft,char \*\*outbuf,size\_t \*outbytesleft); 此函数从inbuf中读取字符,转换后输出到outbuf中,inbytesleft用以记录还未转换的字符数,outbytesleft用以记录输出缓冲的剩余空间 **setsockopt:** int setsockopt( SOCKET s, int level, int optname, const char\* optval, int optlen ); s(套接字): 指向一个打开的套接口描述字 level:(级别): 指定选项代码的类型。 SOL\_SOCKET: 基本套接口 IPPROTO\_IP: IPv4套接口 IPPROTO\_IPV6: IPv6套接口 IPPROTO\_TCP: TCP套接口 optname(选项名): 选项名称 optval(选项值): 是一个指向变量的指针 类型:整形,套接口结构, 其他结构类型:linger\{\}, timeval\{ \} optlen(选项长度) :optval 的大小 返回值:标志打开或关闭某个特征的二进制选项 **Linux socket 进程通信:** (1)创建socket,类型为AF\_LOCAL或AF\_UNIX,表示用于进程通信: **\[cpp\]** [view plain][] [copy][view plain] 1. **int** server\_fd; 2. **int** client\_fd;//client file descriptor 3. **struct** sockaddr\_un server\_addr; 4. **struct** sockaddr\_un client\_addr; 5. **size\_t** server\_len,client\_len; 6. 7. //cteate server socket 8. //delete old socket file 9. unlink(SERVER\_NAME); 10. **if** ((server\_fd = socket(AF\_UNIX, SOCK\_STREAM, 0)) == -1) \{ 11. perror("socket"); 12. exit(1); 13. \} (2)命名socket。这里面有一个很关键的东西,socket进程通信命名方式有两种。一是普通的命名,socket会根据此命名创建一个同名的socket文件,客户端连接的时候通过读取该socket文件连接到socket服务端。这种方式的弊端是服务端必须对socket文件的路径具备写权限,客户端必须知道socket文件路径,且必须对该路径有读权限。另外一种命名方式是抽象命名空间,这种方式不需要创建socket文件,只需要命名一个全局名字,即可让客户端根据此名字进行连接。后者的实现过程与前者的差别是,后者在对地址结构成员sun\_path数组赋值的时候,必须把第一个字节置0,即sun\_path\[0\] = 0,下面用代码说明: 第一种方式: server_addr.sun_family = AF_UNIX; strcpy(server_addr.sun_path,SERVER_NAME); server_len = sizeof(struct sockaddr_un); client_len = server_len; connect(server_fd , (const sockaddr*)&addr,server_len ) 第二种方式: **\[cpp\]** [view plain][] [copy][view plain] 1. //name the socket 2. server\_addr.sun\_family = AF\_UNIX; 3. strcpy(server\_addr.sun\_path, SERVER\_NAME); 4. server\_addr.sun\_path\[0\]=0; 5. //server\_len = sizeof(server\_addr); 6. server\_len = strlen(SERVER\_NAME) + offsetof(**struct** sockaddr\_un, sun\_path); 其中,offsetof函数在\#include <stddef.h>头文件中定义。因第二种方式的首字节置0,我们可以在命名字符串SERVER\_NAME前添加一个占位字符串,例如: **\[cpp\]** [view plain][] [copy][view plain] 1. \#define SERVER\_NAME @socket\_server 前面的@符号就表示占位符,不算为实际名称。 UNIX Domain Socket与网络socket编程最明显的不同在于地址格式不同,用结构体sockaddr\_un表示,网络编程的socket地址是IP地址加端口 号,而UNIX Domain Socket的地址是一个socket类型的文件在文件系统中的路径, **signal:** **int** sigprocmask(ubt how,**const** sigset\_t\*set,sigset\_t \*oldset) how:用于指定信号修改的方式,可能选择有三种 SIG\_BLOCK//将set所指向的信号集中包含的信号加到当前的信号掩码中。即信号掩码和set信号集进行或操作。 SIG\_UNBLOCK//将set所指向的信号集中包含的信号从当前的信号掩码中删除。即信号掩码和set进行与操作。 SIG\_SETMASK //将set的值设定为新的进程信号掩码。即set对信号掩码进行了赋值操作。 set:为指向信号集的指针,在此专指新设的信号集,如果仅想读取现在的屏蔽值,可将其置为NULL。 oldset:也是指向信号集的指针,在此存放原来的信号集。可用来检测信号掩码中存在什么信号。 返回说明: 成功执行时,返回0。失败返回-1,errno被设为EINVAL。 **POSIX 线程 – pthread\_sigmask:** 在多线程的程序里,希望只在主线程中处理信号,可以使用 函数: int pthread\_sigmask (int how, const sigset\_t \*set, sigset\_t \*oset) 用作在主调线程里控制信号掩码。 How: SIG\_BLOCK: 结果集是当前集合参数集的并集 SIG\_UNBLOCK: 结果集是当前集合参数集的差集 SIG\_SETMASK: 结果集是由参数集指向的集 头文件: <signal.h> 错误: \[EINVAL\] how不是已定义值 提示: 除非信号在所有的线程里都阻塞,否则总能将异步信号传输给这个进程。 #include <pthread.h> #include <stdio.h> #include <sys/signal.h> #define NUMTHREADS 3 void sighand(int signo); void *threadfunc(void *parm) { pthread_t tid = pthread_self(); int rc; printf("Thread %u entered/n", tid); rc = sleep(30); printf("Thread %u did not get expected results! rc=%d/n", tid, rc); return NULL; } void *threadmasked(void *parm) { pthread_t tid = pthread_self(); sigset_t mask; int rc; printf("Masked thread %lu entered/n", tid); sigfillset(&mask); /* Mask all allowed signals */ rc = pthread_sigmask(SIG_BLOCK, &mask, NULL); if (rc != 0) { printf("%d, %s/n", rc, strerror(rc)); return NULL; } rc = sleep(15); if (rc != 0) { printf("Masked thread %lu did not get expected results! " "rc=%d /n", tid, rc); return NULL; } printf("Masked thread %lu completed masked work/n", tid); return NULL; } int main(int argc, char **argv) { int rc; int i; struct sigaction actions; pthread_t threads[NUMTHREADS]; pthread_t maskedthreads[NUMTHREADS]; printf("Enter Testcase - %s/n", argv[0]); printf("Set up the alarm handler for the process/n"); memset(&actions, 0, sizeof(actions)); sigemptyset(&actions.sa_mask); actions.sa_flags = 0; actions.sa_handler = sighand; rc = sigaction(SIGALRM,&actions,NULL); printf("Create masked and unmasked threads/n"); for(i=0; i<NUMTHREADS; ++i) { rc = pthread_create(&threads[i], NULL, threadfunc, NULL); if (rc != 0) { printf("%d, %s/n", rc, strerror(rc)); return -1; } rc = pthread_create(&maskedthreads[i], NULL, threadmasked, NULL); if (rc != 0) { printf("%d, %s/n", rc, strerror(rc)); return -1; } } sleep(3); printf("Send a signal to masked and unmasked threads/n"); for(i=0; i<NUMTHREADS; ++i) { rc = pthread_kill(threads[i], SIGALRM); rc = pthread_kill(maskedthreads[i], SIGALRM); } printf("Wait for masked and unmasked threads to complete/n"); for(i=0; i<NUMTHREADS; ++i) { rc = pthread_join(threads[i], NULL); rc = pthread_join(maskedthreads[i], NULL); } printf("Main completed/n"); return 0; } void sighand(int signo) { pthread_t tid = pthread_self(); printf("Thread %lu in signal handler/n", tid); return; } 程序返回: Enter Testcase - ./pthread\_sigmask\_test Set up the alarm handler for the process Create masked and unmasked threads Thread 3086597040 entered Masked thread 3076107184 entered Thread 3065617328 entered Masked thread 3055127472 entered Thread 3044637616 entered Masked thread 3034147760 entered Send a signal to masked and unmasked threads Wait for masked and unmasked threads to complete Thread 3086597040 in signal handler Thread 3086597040 did not get expected results! rc=27 Thread 3065617328 in signal handler Thread 3065617328 did not get expected results! rc=27 Thread 3044637616 in signal handler Thread 3044637616 did not get expected results! rc=27 Masked thread 3076107184 completed masked work Masked thread 3055127472 completed masked work Masked thread 3034147760 completed masked work Main completed [view plain]: http://blog.csdn.net/xnwyd/article/details/7359506#
还没有评论,来说两句吧...