Home php c# sql c c++ javascript python java go android git linux asp.net django .net node.js ios xcode cocoa iphone mysql tomcat mongodb bash objective-c scala visual-studio apache elasticsearch jar eclipse jquery ruby-on-rails ruby rubygems android-studio spring lua sqlite emacs ubuntu perl docker swift amazon-web-services svn html ajax xml java-ee maven intellij-idea rvm macos unix css ipad postgresql css3 json windows-server vue.js typescript oracle hibernate internet-explorer github tensorflow laravel symfony redis html5 google-app-engine nginx firefox sqlalchemy lucene erlang flask vim solr webview facebook zend-framework virtualenv nosql ide twitter safari flutter bundle phonegap centos Register | Login | Edit Tags | New Questions | 繁体 | 简体


10 questions online user: 47

0
votes
answers
10 views
+10

mq_notify只啓動一個線程

2

我想用mq_notify調用來啓動一個POSIX消息隊列的線程。一切似乎都正確,但我只能得到一個線程,它處理所有消息,但它永遠不會終止。我的印象是我會得到新線程來處理,這看起來不正確。mq_notify只啓動一個線程

沙发
0
3

首先,mq_notify()一次只能啓動一個線程。其次,每次將消息放入隊列時線程都不會啓動;它們只在空隊列獲取新消息時才啓動。第三,mq_notify()是一次性交易。一旦一個線程被觸發,如果你想在下一次空隊列收到消息時觸發一個新線程,你需要用mq_notify()重新註冊。通常你的threadfunc應該做的第一件事就是重新註冊。

由於您正在啓動一個線程並處理消息,我的猜測是您沒有像O_NONBLOCK那樣打開隊列,或者使用mq_setattr()重置它。當一個線程觸發時,您希望排除所有消息的隊列,以便下一次啓動另一個線程。如果隊列處於阻塞模式,您將在收到最後一條消息後阻塞,線程將永遠不會結束。在非阻塞模式下,您希望繼續閱讀,直到獲得errno == EAGAIN,然後結束該線程。你應該很樂意用新的線程去下一批消息。

+0

非常感謝Duck。非阻塞做到了。回想起來似乎很明顯。 – 2011-06-07 01:42:47

0
votes
answers
10 views
+10

C++ boost ::線程,如何啓動線程內的線程

6

如何在對象內啓動線程?例如,C++ boost ::線程,如何啓動線程內的線程

class ABC 
{ 
public: 
void Start(); 
double x; 
boost::thread m_thread; 
}; 

ABC abc; 
... do something here ... 
... how can I start the thread with Start() function?, ... 
... e.g., abc.m_thread = boost::thread(&abc.Start()); ... 

這樣,以後我可以這樣做,

abc.thread.interrupt(); 
abc.thread.join(); 

感謝。

沙发
0
6

使用boost.bind:

boost::thread(boost::bind(&ABC::Start, abc)); 

你可能需要一個指針(或一個shared_ptr):

boost::thread* m_thread; 
m_thread = new boost::thread(boost::bind(&ABC::Start, abc)); 
+0

謝謝蓋伊,它工作得很好。 – 2607 2012-02-26 23:50:26

板凳
0
15

你既不需要綁定,也不指針。

boost::thread m_thread; 
//... 
m_thread = boost::thread(&ABC::Start, abc); 
+0

+1:你說得對。有一個參數相當於使用綁定的構造函數。我更喜歡綁定,因爲我發現它更具可讀性。還有支持移動線程,我想我喜歡指針,因爲我知道發生了什麼(複製與移動),但希望一切都朝着移動... – 2012-02-27 21:26:59

+0

這應該是接受的答案 – user463035818 2017-06-01 14:08:43

0
votes
answers
8 views
+10

從Linux上的NodeJS打印到Star TSP143LAN,格式爲

0

我已經安裝了適當的CUPS驅動程序:我可以使用任何具有打印功能的應用程序(如Chrome)打印到我的Star TSP143LAN。我可以使用節點打印機模塊通過指定打印機名稱或打印機的網絡地址以及將打印模式設置爲TEXT來打印到此打印機。從Linux上的NodeJS打印到Star TSP143LAN,格式爲

但我似乎無法格式化使用節點打印機庫從NodeJS打印的內容。如果我將模式設置爲RAW併發送命令,如本打印機的Star命令行模擬器手冊中所指定的那樣,節點打印機將報告成功的打印,但沒有任何反應。它不打印。

我試圖發送這些RAW命令,因爲我想進行各種格式化操作,如使字體變大或變粗等等。

我試過節點熱敏打印機模塊,但我沒有運氣。

我一直在網上搜尋一些關於這個問題的幫助,但是我一直沒能找到太多。我已經看到它提到TSP143局域網不像其他明星產品那樣進行通信,最好使用Star的驅動程序作爲中介,但我不確定這意味着什麼。 (當我試圖從節點打印機打印時指定打印機的類名稱時,我想我可能已經這麼做了......)

我沒有太多的麻煩將Star Swift SDK安裝到iOS應用程序中並進行格式化那裏的操作。但我需要從Linux上的NodeJS環境打印。我很茫然。

如果有任何人向誰這聽起來很熟悉,可以點我在正確的方向,我會非常感激......

謝謝!

沙发
0
0

經過相當多的研究後,它看起來像Star TSP100/TSP143 LAN無法使用線路模式命令或Linux的ESC/POS進行打印:解決方案是從HTML生成PDF(使用wkhtmltopdf)然後使用節點打印機庫(https://github.com/tojocky/node-printer)打印PDF。我還沒有找到更好的方式來正確格式化打印。

0
votes
answers
8 views
+10

當焦油和分裂時使用所有核心

0

我想讓我的tar命令使用所有內核(8),當我打包到如下所示的單個包中時,我得到它的工作:tar -I pigz -cf packed.tar.gz folder/。 它正在工作,它使用所有內核。當焦油和分裂時使用所有核心

但是,當我需要打包成多個文件時,我無法使用它來使用所有內核,這是我的命令:tar cvzf - folder/ | split --bytes=4GB - packed.tar.gz。 如何讓這個命令使用所有核心而不僅僅是一個?

感謝您的所有意見。

沙发
0
2

對於多線程文件壓縮工具pigz:

tar -I pigz -cvf - folder/ | split --bytes=4GB - packed.tar.gz 
0
votes
answers
7 views
+10

linux shell複製粘貼將?0和1?符號添加到字符串

0

我正在運行Ubuntu 16.04。最近,我在通過剪貼板複製粘貼時遇到以下奇怪的行爲,例如,假設我想克隆一些存儲庫。所以,我複製下面的字符串:linux shell複製粘貼將?0和1?符號添加到字符串

https://github.com/tensorflow/tensorflow

,然後使用Ctrl + Shift + V粘貼到我的殼git clone之後。我希望:

$ git clone https://github.com/tensorflow/tensorflow

而是我看到

$ git clone ~0https://github.com/tensorflow/tensorflow1~

這不會發生的事情,我還沒有想通了,是什麼原因導致這種令人討厭的行爲。任何人遇到這種情況,並有人發現如何擺脫它?

+1

也許這[鏈接](https://unix.stackexchange.com/questions/196098/copy-paste-in-xfce4-terminal-adds-0-and-1)回答你的問題。 – Robin

+0

Stack Overflow是編程和開發問題的網站。這個問題似乎與題目無關,因爲它不涉及編程或開發。請參閱幫助中心的[我可以詢問哪些主題](http://stackoverflow.com/help/on-topic)。也許[超級用戶](http://superuser.com/)或[Unix&Linux堆棧交換](http://unix.stackexchange.com/)會是一個更好的地方。 – jww

沙发
0
-1

嘗試在此處找到解決方案:http://midnight-commander.org/ticket/3207 TL; DR看起來像Ubuntu軟件包中的錯誤。 你可以複製選擇它的文本,並用鼠標按下滾動按鈕粘貼,這樣可以避免你現在遇到的麻煩。

0
votes
answers
7 views
+10

如何在Linux或Mac中編譯用於Windows的靜態.lib庫

1

我正在尋找在Linux或Mac中爲Windows編譯靜態庫的方式,似乎有交叉編譯器爲Windows生成.a庫,如this one,但那是不是我想要的,我想要的是針對Windows的.lib靜態庫文件,最好是Visual Studio。我知道我可以運行Windows虛擬機並使用Visual Studio,但這太重了,無法在命令行中完成。如何在Linux或Mac中編譯用於Windows的靜態.lib庫

沙发
0
1

類Unix操作系統(Linux操作系統,MacOS的,等等)一個靜態庫裝置 對象文件的ar archivear是GNU通用 的目的歸檔器。它並不關心你保存在檔案中的文件類型。當它們碰巧是目標文件時,它只是將其稱爲「靜態庫」的自定義的 。而 它也只是一個ar存檔的定製,稱爲*.a。你可以稱它爲 *.lib,或其他任何東西。

對於Visual Studio,一個靜態庫指的通常是由微軟工具LIB創建PE格式的對象文件 存檔。

Microsoft LIB存檔的格式實際上與Unix ar存檔的格式相同。微軟 剛剛通過它,很久以前。

所以,如果你使用你的發行版的PE交叉編譯 然後再將其歸檔編譯Linux上的一些PE目標文件與ar一個*.lib,你也得爲自己的靜態庫,是很好的在Windows 去與Visual Studio編譯器。

那麼,只要這些目標文件有C二進制接口。 如果它們中的任何一個具有C++接口,則它們是無用的:Microsoft和GCC C++編譯器使用不同的名稱綁定協議,否則ABI不兼容。

演示

我們開始在Linux與靜態庫的一些源代碼:

的hello.c

#include <stdio.h> 

void hello(void) 
{ 
    puts("Hello world"); 
} 

交叉編譯:

$ x86_64-w64-mingw32-gcc-win32 -o hello.obj -c hello.c 

使靜態庫:

$ ar rcs hello.lib hello.obj 

那麼這是怎麼回事程序要與hello.lib鏈接:

爲主。ç

extern void hello(void); 

int main(void) 
{ 
    hello(); 
    return 0; 
} 

現在我們跳進一個Windows 10 VM,我們正在尋找在我們 只是通過共享文件夾中創建的文件:

E:developsoxstatlib>dir 
Volume in drive E is VBOX_imk 
Volume Serial Number is 0000-0804 

Directory of E:developsoxstatlib 

03/12/2017 18:37    72 main.c 
03/12/2017 18:29    978 hello.lib 
03/12/2017 18:26    66 hello.c 
03/12/2017 18:27    832 hello.obj 
       4 File(s)   1,948 bytes 
       0 Dir(s) 153,282,871,296 bytes free 

編譯並鏈接我們的程序:

E:developsoxstatlib>cl /Fehello.exe main.c hello.lib 
Microsoft (R) C/C++ Optimizing Compiler Version 19.11.25547 for x64 
Copyright (C) Microsoft Corporation. All rights reserved. 

main.c 
Microsoft (R) Incremental Linker Version 14.11.25547.0 
Copyright (C) Microsoft Corporation. All rights reserved. 

/out:hello.exe 
main.obj 
hello.lib 

運行:

E:developsoxstatlib>hello 
Hello world 
+0

'extern「C」'怎麼樣?這有助於與gcc/VisualStudio兼容的C++名稱修改? –

+1

@BarmakShemirani確實,雖然'extern「C」'範圍內的API必須是有效的,開頭的C API必須是 。我已經使措辭更準確。 –

+0

非常感謝你這麼詳細的解釋和例子,非常感謝。 – Ryan

0
votes
answers
7 views
+10

如何創建一個簡單的驅動程序? [Ubuntu]

-2

這個想法是創建一個可以通過設備進行通信的驅動程序和用戶應用程序。如何創建一個簡單的驅動程序? [Ubuntu]

當我編譯模塊時,將它附加到內核並創建設備,我沒有得到任何錯誤,但是當我啓動用戶應用程序時,它崩潰了。另外,在崩潰之後,我的電腦變慢了,有時甚至需要重啓我的系統。 我也讀過內核日誌文件,發現這個錯誤:[ 336.741386] BUG: unable to handle kernel NULL pointer dereference at (null)

你能告訴我,如果我的代碼有問題嗎?

驅動程序代碼:

#include <linux/kernel.h> 
#include <linux/module.h> 
#include <linux/fs.h>   // Allows to open/read/write/execute a device 
#include <linux/cdev.h>   // Char driver; makes cdev available 
#include <linux/semaphore.h> // Used to access semaphores; used for synchronization for avoiding crashes 
#include <asm/uaccess.h>  // Copy_to_user;copy_from_user 

struct fake_device{ 
    char data[100]; 
    struct semaphore sem; 
}virtual_device; 

struct cdev *mcdev;  // My Char device driver 
int major_number; 
int ret; 

dev_t dev_num; 

#define DEVICE_NAME "looperdevice" 

int device_open(struct inode *inode, struct file *filp){ 
    if(down_interruptible(&virtual_device.sem) != 0){ 
     printk(KERN_ALERT "looperdevice: could not lock device during open"); 
     return -1; 
    } 
    printk(KERN_INFO "looperdevice: opened device"); 
    return 0; 

} 
ssize_t device_read(struct file* filp, char* bufStoreData, size_t bufCount, loff_t* curOffset){ 
    printk(KERN_INFO "looperdevice: Reading from device"); 
    ret = copy_to_user(bufStoreData, virtual_device.data, bufCount); 
    return ret; 
} 

ssize_t device_write(struct file* filp, const char* bufSourceData, size_t bufCount, loff_t* curOffset){ 
    printk(KERN_INFO "looperdevice: Writing to device"); 
    ret = copy_from_user(virtual_device.data, bufSourceData, bufCount); 
    return ret; 
} 

int device_close(struct inode *inode, struct file *filp){ 
    printk(KERN_INFO "looperdevice: Closing device"); 
    up(&virtual_device.sem); // Set semaphore up 
    return 0; 
} 


struct file_operations fops = { 
    .owner = THIS_MODULE, 
    .open = device_open, 
    .release = device_close, 
    .write = device_write, 
    .read = device_read 
}; 

static int driver_entry(void){ 
    /* 
    Register our device in the system 
    alloc_chrdev_region(dev_t*, uint fminor, uint count, char* name) 
    */ 
    ret = alloc_chrdev_region(&dev_num, 0, 1, DEVICE_NAME); // Will store minor and max number into dev_num, for future extraction 
    if (ret < 0){ 
     printk(KERN_ALERT "looperdevice: failed to allocate a major number"); 
     return ret; 
    } 
    // Extracting major number 
    major_number = MAJOR(dev_num); 
    printk(KERN_INFO "looperdevice: major_number extracted, %d", major_number); 
    printk(KERN_INFO "	use "mknod /dev/%s c %d 0" for device file",DEVICE_NAME, major_number); 

    mcdev = cdev_alloc(); // Create our cdev structure already initializated 
    mcdev->ops = &fops;  // struct file operations 
    mcdev->owner = THIS_MODULE; 
    // Now that we created the cdev we have to add it to the kernel 
    // int cdev_add(struct cdev* dev, dev_t num, unsigned int count) 
    ret = cdev_add(mcdev, dev_num, 1); 
    if (ret < 0){ 
     printk(KERN_ALERT "looperdevice: unable to add cdev to kernel"); 
     return ret; 

    } 
    // Initialize our semaphore 
    sema_init(&virtual_device.sem, 1); 

    return 0; 
} 
static void driver_exit(void){ 
    cdev_del(mcdev); 
    unregister_chrdev_region(dev_num,1); 
    printk(KERN_ALERT "looperdevice: Unloaded module"); 

} 

module_init(driver_entry); 
module_exit(driver_exit); 

用戶應用代碼:

#include <stdio.h> 
#include <stdlib.h> 
#include <fcntl.h> 

#define DEVICE "/dev/looperdevice" 

int main(){ 
    int i, fd, ch; 
    char write_buf[100], read_buf[100]; 
    fd = open(DEVICE, O_RDWR); 
    if (fd == -1){ 
     printf("file %s either does not exist or has been locked by another process
", DEVICE); 
     exit(-1); 
    } 
    printf("Looper application v0.1 Beta
"); 
    while (ch != 3){ 
     printf("--------------MENU-------------
"); 
     printf("1. Read from device
2. Write to device
3. Exit"); 
     printf("Choose an option: "); 
     scanf("%d", &ch); 
     switch(ch){ 
      case 1: 
       // reading from device 
       read(fd, read_buf, sizeof(read_buf)); 
       printf("DEVICE: %s
", read_buf); 
       break; 
      case 2: 
       // Writing to device 
       printf("Enter Data: "); 
       gets(write_buf); 
       write(fd, write_buf, sizeof(write_buf)); 
       break; 
      case 3: 
       exit(0); 
       break; 
      default: 
       printf("Invalid option
"); 
       break; 
     } 
    } 
    return 0; 
} 

內核日誌文件:

[ 321.242532] driver: module license 'unspecified' taints kernel. 
[ 321.242534] Disabling lock debugging due to kernel taint 
[ 321.243024] looperdevice: major_number extracted, 241 
[ 321.243026] use "mknod /dev/looperdevice c 241 0" for device file 
[ 321.243028] looperdevice: unable to add cdev to kernel 
[ 336.741386] BUG: unable to handle kernel NULL pointer dereference at           (null) 
[ 336.741524] IP: __down_interruptible+0x51/0xf0 
[ 336.741563] PGD a3279067 
[ 336.741564] PUD a3278067 
[ 336.741589] PMD 0 

[ 336.741650] Oops: 0002 [#1] SMP 
[ 336.741680] Modules linked in: driver(POE) ccm bnep pci_stub vboxpci(OE) vboxnetadp(OE) vboxnetflt(OE) vboxdrv(OE) dm_crypt dell_wmi sparse_keymap uvcvideo videobuf2_vmalloc videobuf2_memops videobuf2_v4l2 videobuf2_core videodev media dell_laptop dell_smbios btusb dcdbas btrtl btbcm btintel dell_smm_hwmon bluetooth arc4 iwldvm mac80211 intel_rapl x86_pkg_temp_thermal intel_powerclamp snd_hda_codec_hdmi coretemp kvm_intel kvm irqbypass crct10dif_pclmul crc32_pclmul ghash_clmulni_intel pcbc snd_hda_codec_idt snd_hda_codec_generic aesni_intel aes_x86_64 crypto_simd glue_helper cryptd intel_cstate intel_rapl_perf snd_hda_intel snd_hda_codec snd_hda_core snd_hwdep snd_pcm input_leds snd_seq_midi joydev snd_seq_midi_event serio_raw snd_rawmidi snd_seq binfmt_misc iwlwifi snd_seq_device snd_timer cfg80211 
[ 336.742291] lpc_ich shpchp snd mei_me soundcore mei wmi dell_smo8800 mac_hid dell_rbtn parport_pc ppdev lp parport autofs4 hid_generic usbhid hid i915 ahci libahci psmouse i2c_algo_bit drm_kms_helper sdhci_pci sdhci syscopyarea sysfillrect e1000e sysimgblt fb_sys_fops drm ptp pps_core fjes video 
[ 336.742530] CPU: 2 PID: 3578 Comm: app Tainted: P   OE 4.10.0-37-generiC#41~16.04.1-Ubuntu 
[ 336.742607] Hardware name: Dell Inc. Latitude E5430 vPro/0NVFXC, BIOS A16 08/19/2015 
[ 336.742673] task: ffff96ace1e08000 task.stack: ffffb4d500b68000 
[ 336.742727] RIP: 0010:__down_interruptible+0x51/0xf0 
[ 336.742771] RSP: 0018:ffffb4d500b6bba0 EFLAGS: 00010046 
[ 336.742817] RAX: 0000000000000000 RBX: ffffffffc0be84c8 RCX: 0000000000000002 
[ 336.742878] RDX: ffffffffc0be84d0 RSI: 0000000000000292 RDI: ffffffffc0be84c8 
[ 336.742938] RBP: ffffb4d500b6bbe8 R08: 0000000000000000 R09: 0000000000000000 
[ 336.742998] R10: 00000000000000f1 R11: ffff96acaa4d6338 R12: 7fffffffffffffff 
[ 336.743058] R13: ffff96ace1e08000 R14: ffff96ace294eb00 R15: ffffffffaf9c5c80 
[ 336.743120] FS: 00007fadeade0700(0000) GS:ffff96ad5e300000(0000) knlGS:0000000000000000 
[ 336.743188] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 
[ 336.743237] CR2: 0000000000000000 CR3: 00000000a337a000 CR4: 00000000001406e0 
[ 336.743298] Call Trace: 
[ 336.743329] ? exact_lock+0x11/0x20 
[ 336.743363] down_interruptible+0x4b/0x60 
[ 336.743403] device_open+0x15/0x30 [driver] 
[ 336.743442] chrdev_open+0xbf/0x1b0 
[ 336.743477] do_dentry_open+0x208/0x310 
[ 336.743514] ? cdev_put+0x30/0x30 
[ 336.743548] vfs_open+0x4c/0x70 
[ 336.743581] ? may_open+0x9b/0x100 
[ 336.743620] path_openat+0x2ac/0x1430 
[ 336.743660] ? page_add_file_rmap+0x58/0x140 
[ 336.743702] do_filp_open+0x91/0x100 
[ 336.743738] ? __alloc_fd+0x46/0x170 
[ 336.743774] do_sys_open+0x12d/0x280 
[ 336.743809] SyS_open+0x1e/0x20 
[ 336.743841] entry_SYSCALL_64_fastpath+0x1e/0xad 
[ 336.743883] RIP: 0033:0x7fadea912010 
[ 336.743916] RSP: 002b:00007ffcf9ce3238 EFLAGS: 00000246 ORIG_RAX: 0000000000000002 
[ 336.743982] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007fadea912010 
[ 336.744042] RDX: 00007ffcf9ce3428 RSI: 0000000000000002 RDI: 00000000004009b8 
[ 336.746348] RBP: 00007ffcf9ce3330 R08: 00000000004009a0 R09: 00007fadeabf5ab0 
[ 336.748583] R10: 000000000000069d R11: 0000000000000246 R12: 00000000004006b0 
[ 336.750831] R13: 00007ffcf9ce3410 R14: 0000000000000000 R15: 0000000000000000 
[ 336.753533] Code: 00 00 48 83 e4 f0 48 83 ec 30 65 48 8b 04 25 28 00 00 00 48 89 44 24 28 31 c0 48 8b 47 10 48 89 14 24 48 89 67 10 48 89 44 24 08 <48> 89 20 4c 89 6c 24 10 c6 44 24 18 00 eb 38 4d 85 e4 7e 52 49 
[ 336.758651] RIP: __down_interruptible+0x51/0xf0 RSP: ffffb4d500b6bba0 
[ 336.761183] CR2: 0000000000000000 
[ 336.775501] ---[ end trace 3fcbe3000944b329 ]--- 

我希望你能幫助我:)

+1

'當我編譯模塊,將其連接到內核和創建設備,我沒有得到任何error' - 根據日誌,你**將模塊加載到內核時出現錯誤**:'looperdevice:無法將cdev添加到內核'。根據驅動程序的代碼,模塊的加載應該被取消(因爲返回負值),所以進一步的「BUG」看起來可疑。 – Tsyvarev

沙发
0
0

解決方案是添加模塊蝨子NSE:

MODULE_LICENSE("GPL"); 

謝謝:)

0
votes
answers
7 views
+10

端口9999服務器不接受請求

0

我想在亞馬遜EC2實例上部署我的套接字[phpws庫]。爲此,我部署了代碼並運行套接字。我選擇了端口9999進行套接字握手,但它不起作用。 我試圖捕獲請求該服務器上通過命令:端口9999服務器不接受請求

sudo tcpdump -i any port 9999 

然後我打這個端口,我沒有收到任何請求。我認爲這是因爲iptables。所以我通過命令檢查它:

sudo iptables -L 

但它清楚地顯示允許所有請求。這裏是輸出:

鏈INPUT(策略ACCEPT) 目標PROT選擇源目的地

鏈FORWARD(策略ACCEPT) 目標PROT選擇源目的地

鏈OUTPUT(策略ACCEPT) 目標保護人選擇來源目的地

在這一點上,我很無能如何前進。任何幫助都是溫和的。尋找答案。

+0

Stack Overflow是編程和開發問題的網站。這個問題似乎與題目無關,因爲它不涉及編程或開發。請參閱幫助中心的[我可以詢問哪些主題](http://stackoverflow.com/help/on-topic)。也許[超級用戶](http://superuser.com/)或[Unix&Linux堆棧交換](http://unix.stackexchange.com/)會是一個更好的地方。 – jww

沙发
0
1

您還必須在附加到EC2實例的AWS安全組中打開端口9999

+0

是的,自從過去幾個小時以來,我一直在與這個愚蠢的錯誤作鬥爭。非常感謝您的幫助。 – Pradeep

0
votes
answers
6 views
+10

如何檢查啓動了哪個進程sys_open

1

我正在學習操作系統課程,我們在Linux(Red hat 8.0)中工作。我試圖實現一個文件打開,關閉跟蹤器,將爲每個進程保存它打開和關閉的文件的歷史記錄。我期望sys_open,close也接受進程id,並且我可以使用它來訪問啓動調用並更新它的進程的歷史記錄(使sysopen的更新部分,關閉函數)。但是,這些函數不接受pid作爲參數,所以我在關於如何將啓動/關閉文件關聯到啓動它的進程方面有些遺憾。我唯一的猜測是,因爲在任何時候只有一個活動進程,它的元數據必須以某種方式是全局的,但我不知道在哪裏或如何找到它。任何意見,將不勝感激。如何檢查啓動了哪個進程sys_open

0
votes
answers
6 views
+10

sys_open是如何工作的?

0

我寫了一個簡單的字符設備驅動程序(mydev),其中包含「打開」文件操作。sys_open是如何工作的?

在用戶空間應用程序中,我打開此驅動程序節點。使用open(「/ dev/mydev」,O_RDONLY); open()系統調用在內部調用sys_open()。

我只想知道sys_open()函數如何調用我的驅動程序的打開文件操作。 VFS如何處理這個問題,它在內部調用函數。

沙发
0
1

我發現在瞭解Linux內核的書的答案,在部分12.5.1

操作步驟,

  1. 調用的getName()來讀取進程的地址空間中的文件路徑名。

  2. 調用get_unused_fd()在current-> files-> fd中查找一個空插槽。 對應的索引(新文件描述符)存儲在fd局部變量中。

  3. 調用filp_open()函數,以參數的形式傳遞路徑名,訪問模式標誌和權限位掩碼 。該功能依次執行以下步驟: 步驟:

    a。調用get_empty_filp()來獲得一個新的文件對象。

    b。根據標誌和模式參數值 設置文件對象的f_flags和f_mode字段。

    c。調用open_namei(),執行以下操作:

    i. Invokes lookup_dentry() to interpret the file pathname and gets the 
         dentry object associated with the requested file. 
    
        ii. Performs a series of checks to verify whether the process is permitted 
         to open the file as specified by the values of the flags parameter. If so, 
         returns the address of the dentry object; otherwise, returns an error code. 
    

    d。如果訪問權限用於寫入,則檢查 inode對象的i_writecount字段的值。負值表示該文件已被內存映射, 指定必須拒絕寫入訪問(請參閱章節15.2中的第15.2節)。在這種情況下,返回一個錯誤代碼。任何其他值都指定實際寫入文件的進程數量爲 。在後一種情況下, 遞增計數器。

    e。初始化文件對象的字段;特別是將f_op字段設置爲inode對象的i_op-> default_file_ops字段的內容。這將爲將來的文件操作設置所有正確的功能。 f。如果定義了(默認)文件操作的打開方法,則調用它。 g。清除f_flags中的O_CREAT,O_EXCL,O_NOCTTY和O_TRUNC標誌。 h。返回文件對象的地址。

  4. 將current-> files-> fd [fd]設置爲文件對象的地址。
  5. 返回fd。